diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index c22e6fabec..b37c9d4f4b 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -278,6 +278,26 @@ pipeline { } } } + stage ("SA B200 Sanity Check") { + when { expression {doMandatoryTests} } + steps { + script { + triggerSlaveJob ('RAN-SA-B200-Module-SABOX-Container', 'Test-SA-B200') + } + } + post { + always { + script { + finalizeSlaveJob('RAN-SA-B200-Module-SABOX-Container') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test OAI NR UE - OAI gNB - TDD - Band 78 - N300") { when { expression {doMandatoryTests} } steps { diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry index bc1a80ba61..feb1807c91 100644 --- a/ci-scripts/Jenkinsfile-push-registry +++ b/ci-scripts/Jenkinsfile-push-registry @@ -66,7 +66,7 @@ pipeline { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password'] ]) { - def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"] + def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "proxy"] sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1" listOfImages.eachWithIndex { item, iindex -> sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop" diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb index c3b825ec06..fb52316920 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb @@ -36,6 +36,9 @@ def testStageName = params.pipelineTestStageName // Name of the phone resource def ciSmartPhoneResource = params.smartphonesResource +// Name of the phone resource +def ciEpcResource = params.epcResource + // Global Parameters. Normally they should be populated when the master job // triggers the slave job with parameters def eNB_Repository @@ -51,7 +54,7 @@ pipeline { options { disableConcurrentBuilds() ansiColor('xterm') - lock (ciSmartPhoneResource) + lock(extra: [[resource: ciEpcResource]], resource: ciSmartPhoneResource) } stages { stage ("Verify Parameters") { @@ -216,6 +219,76 @@ pipeline { } } } + stage ("Terminate") { + parallel { + stage('Terminate UE') { + // Bypassing this stage if there are no abd server defined + when { + expression { params.ADB_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate UE\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}" + } + } + } + stage('Terminate eNB') { + steps { + echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + } + stage('Terminate SPGW') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + stage('Terminate MME') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate MME\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + stage('Terminate HSS') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate HSS\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + } + } stage('Log Collection') { parallel { stage('Log Collection (eNB - Build)') { @@ -242,7 +315,7 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] ]) { echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" @@ -259,6 +332,116 @@ pipeline { } } } + stage('Log Collection (SPGW)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("spgw.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "spgw.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (MME)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("mme.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "mme.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (HSS)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("hss.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "hss.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Ping)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ping.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ping.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Iperf)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("iperf.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "iperf.log.${env.BUILD_ID}.zip" + } + } + } + } } } } diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa index 3616b2c404..8e81b75e58 100644 --- a/ci-scripts/Jenkinsfile-trig-nsa +++ b/ci-scripts/Jenkinsfile-trig-nsa @@ -20,6 +20,9 @@ * contact@openairinterface.org */ +// necessary for reading JSON +import groovy.json.JsonSlurper + // Template Jenkins Declarative Pipeline script to run Test w/ RF HW // Location of the python executor node shall be in the same subnet as the others servers @@ -37,12 +40,12 @@ pipeline { stages { stage ("Launcher") { steps { - script { - //retrieve MR that are opened nd with tag NSA - MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true ' - echo "List of selected MR:\n${MR_LIST}" - def MR_ARRAY = MR_LIST.split('\n') - //for every selected MR, retrieve the branch name and the latest commit + script { + // retrieve MR that are opened nd with tag NSA + MR_LIST = sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq -cj "[.[].iid]"' + echo "List of selected MRs: ${MR_LIST.trim()}" + def MR_ARRAY = new JsonSlurper().parseText(MR_LIST.trim()) + // for every selected MR, retrieve the branch name and the latest commit for (MR in MR_ARRAY) { SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """ SRC_BRANCH=SRC_BRANCH.trim() diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index 51fc4a264e..76ebaf0f97 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -50,7 +50,7 @@ amarisoft_ue_1: WakeupScript : none DetachScript : none #end - Cmd : /root/NV17-12-21/ue/lteue + Cmd : /root/NV18-06-2022/ue/lteue Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg Duration : 60 Ping : /tmp/test_ue1.log @@ -71,7 +71,7 @@ amarisoft_ue_2: WakeupScript : none DetachScript : none #end - Cmd : /root/NV17-12-21/ue/lteue + Cmd : /root/NV18-06-2022/ue/lteue Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario Duration : 60 Ping : diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 259db7bffe..8f992689e2 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -74,6 +74,7 @@ class Containerize(): self.eNB2SourceCodePath = '' self.forcedWorkspaceCleanup = False self.imageKind = '' + self.proxyCommit = None self.eNB_instance = 0 self.eNB_serverId = ['', '', ''] self.yamlPath = ['', '', ''] @@ -421,6 +422,124 @@ class Containerize(): HTML.CreateHtmlTabFooter(False) sys.exit(1) + def BuildProxy(self, HTML): + if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.eNB_serverId[self.eNB_instance] == '0': + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + lSourcePath = self.eNBSourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '1': + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + lSourcePath = self.eNB1SourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '2': + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + lSourcePath = self.eNB2SourceCodePath + if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.proxyCommit is None: + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter (need proxyCommit for proxy build)') + logging.debug('Building on server: ' + lIpAddr) + mySSH = SSH.SSHConnection() + mySSH.open(lIpAddr, lUserName, lPassWord) + + # Check that we are on Ubuntu + mySSH.command('hostnamectl', '\$', 5) + result = re.search('Ubuntu', mySSH.getBefore()) + self.host = result.group(0) + if self.host != 'Ubuntu': + logging.error('\u001B[1m Can build proxy only on Ubuntu server\u001B[0m') + mySSH.close() + sys.exit(1) + + self.cli = 'docker' + self.cliBuildOptions = '--no-cache' + + # Workaround for some servers, we need to erase completely the workspace + if self.forcedWorkspaceCleanup: + mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + + oldRanCommidID = self.ranCommitID + oldRanRepository = self.ranRepository + oldRanAllowMerge = self.ranAllowMerge + self.ranCommitID = self.proxyCommit + self.ranRepository = 'https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy.git' + self.ranAllowMerge = False + self._createWorkspace(mySSH, lPassWord, lSourcePath) + # to prevent accidentally overwriting data that might be used later + self.ranCommitID = oldRanCommidID + self.ranRepository = oldRanRepository + self.ranAllowMerge = oldRanAllowMerge + + # Let's remove any previous run artifacts if still there + mySSH.command(self.cli + ' image prune --force', '\$', 30) + # Remove any previous proxy image + mySSH.command(self.cli + ' image rm oai-lte-multi-ue-proxy:latest || true', '\$', 30) + + tag = self.proxyCommit + logging.debug('building L2sim proxy image for tag ' + tag) + # check if the corresponding proxy image with tag exists. If not, build it + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5) + buildProxy = mySSH.getBefore().count('o such image') != 0 + if buildProxy: + mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target oai-lte-multi-ue-proxy --tag proxy:' + tag + ' --file docker/Dockerfile.ubuntu18.04 . > cmake_targets/log/proxy-build.log 2>&1', '\$', 180) + # Note: at this point, OAI images are flattened, but we cannot do this + # here, as the flatten script is not in the proxy repo + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5) + if mySSH.getBefore().count('o such image') != 0: + logging.error('\u001B[1m Build of L2sim proxy failed\u001B[0m') + mySSH.close() + HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTabFooter(False) + sys.exit(1) + else: + logging.debug('L2sim proxy image for tag ' + tag + ' already exists, skipping build') + + # retag the build images to that we pick it up later + mySSH.command('docker image tag proxy:' + tag + ' oai-lte-multi-ue-proxy:latest', '\$', 5) + + # no merge: is a push to develop, tag the image so we can push it to the registry + if not self.ranAllowMerge: + mySSH.command('docker image tag proxy:' + tag + ' proxy:develop', '\$', 5) + + # we assume that the host on which this is built will also run the proxy. The proxy + # currently requires the following command, and the docker-compose up mechanism of + # the CI does not allow to run arbitrary commands. Note that the following actually + # belongs to the deployment, not the build of the proxy... + logging.warning('the following command belongs to deployment, but no mechanism exists to exec it there!') + mySSH.command('sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up', '\$', 5) + + # Analyzing the logs + if buildProxy: + self.testCase_id = HTML.testCase_id + mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) + mySSH.command('mkdir -p proxy_build_log_' + self.testCase_id, '\$', 5) + mySSH.command('mv log/* ' + 'proxy_build_log_' + self.testCase_id, '\$', 5) + if (os.path.isfile('./proxy_build_log_' + self.testCase_id + '.zip')): + os.remove('./proxy_build_log_' + self.testCase_id + '.zip') + if (os.path.isdir('./proxy_build_log_' + self.testCase_id)): + shutil.rmtree('./proxy_build_log_' + self.testCase_id) + mySSH.command('zip -r -qq proxy_build_log_' + self.testCase_id + '.zip proxy_build_log_' + self.testCase_id, '\$', 5) + mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.') + # don't delete such that we might recover the zips + #mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5) + + # Cleaning any created tmp volume + mySSH.command(self.cli + ' volume prune --force || true','\$', 15) + mySSH.close() + + logging.info('\u001B[1m Building L2sim Proxy Image Pass\u001B[0m') + HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize) + def Copy_Image_to_Test_Server(self, HTML): imageTag = 'develop' if (self.ranAllowMerge): @@ -567,8 +686,10 @@ class Containerize(): if status: HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) else: + self.exitStatus = 1 HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) + def UndeployObject(self, HTML, RAN): if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress @@ -588,7 +709,7 @@ class Containerize(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - logging.debug('\u001B[1m Deploying OAI Object on server: ' + lIpAddr + '\u001B[0m') + logging.debug('\u001B[1m Undeploying OAI Object from server: ' + lIpAddr + '\u001B[0m') mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 9d5ae84038..32d9c48966 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -1329,7 +1329,7 @@ class OaiCiTest(): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: SSH.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) + self.UEDevices = re.findall('\r\n([A-Za-z0-9]+)\tdevice',SSH.getBefore()) #report number and id of devices found msg = "UEDevices found by GetAllUEDevices : " + " ".join(self.UEDevices) logging.debug(msg) @@ -1379,8 +1379,7 @@ class OaiCiTest(): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: SSH.command('lsusb | egrep --colour=never "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - #self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) + self.CatMDevices = re.findall('\r\n([A-Za-z0-9_]+)',SSH.getBefore()) else: if (os.path.isfile('./modules_list.txt')): os.remove('./modules_list.txt') @@ -2046,7 +2045,7 @@ class OaiCiTest(): req_bandwidth = '%.1f Gbits/sec' % req_bw req_bw = req_bw * 1000000000 - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', SSH.getBefore()) + result = re.search('Server Report:\r\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', SSH.getBefore()) if result is not None: bitrate = result.group('bitrate') packetloss = result.group('packetloss') @@ -2262,7 +2261,7 @@ class OaiCiTest(): def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue,SSH): - result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore()) + result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P[0-9\.]+)%\)) +(?:|receiver)\r\n(?:|\[ *\d+\] Sent \d+ datagrams)\r\niperf Done\.', SSH.getBefore()) if result is None: result = re.search('(?Piperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore()) lock.acquire() @@ -3865,7 +3864,7 @@ class OaiCiTest(): SSH = sshconnection.SSHConnection() SSH.open(IPAddress, UserName, Password) SSH.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) + result = re.search('Description:\t(?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) if result is not None: OsVersion = result.group('os_type') logging.debug('OS is: ' + OsVersion) @@ -3883,13 +3882,13 @@ class OaiCiTest(): logging.debug('OS is: ' + OsVersion) HTML.OsVersion[idx]=OsVersion SSH.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) + result = re.search('uname -r\r\n(?P[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) if result is not None: KernelVersion = result.group('kernel_version') logging.debug('Kernel Version is: ' + KernelVersion) HTML.KernelVersion[idx]=KernelVersion - SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', SSH.getBefore()) + SSH.command('dpkg --list | egrep --color=never libuhd', '\$', 5) + result = re.search('libuhd.*:amd64 *(?P[0-9\.]+)', SSH.getBefore()) if result is not None: UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + UhdVersion) @@ -3902,7 +3901,7 @@ class OaiCiTest(): logging.debug('UHD Version is: ' + UhdVersion) HTML.UhdVersion[idx]=UhdVersion SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 180) - usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) + usrp_boards = re.findall('product: ([0-9A-Za-z]+)', SSH.getBefore()) count = 0 for board in usrp_boards: if count == 0: @@ -3914,14 +3913,18 @@ class OaiCiTest(): logging.debug('USRP Board(s) : ' + UsrpBoard) HTML.UsrpBoard[idx]=UsrpBoard SSH.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', SSH.getBefore()) + result = re.search('CPU\(s\): *(?P[0-9]+)', SSH.getBefore()) if result is not None: CpuNb = result.group('nb_cpus') logging.debug('nb_cpus: ' + CpuNb) HTML.CpuNb[idx]=CpuNb + result = re.search('Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+)', SSH.getBefore()) + if result is not None: CpuModel = result.group('model') logging.debug('model: ' + CpuModel) HTML.CpuModel[idx]=CpuModel + result = re.search('CPU MHz: *(?P[0-9\.]+)', SSH.getBefore()) + if result is not None: CpuMHz = result.group('cpu_mhz') + ' MHz' logging.debug('cpu_mhz: ' + CpuMHz) HTML.CpuMHz[idx]=CpuMHz diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf index 8f3b03fddc..3b872e56e9 100644 --- a/ci-scripts/conf_files/benetel-5g.conf +++ b/ci-scripts/conf_files/benetel-5g.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf index 51ffb1d5cd..a648db0efe 100644 --- a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( { diff --git a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf index eac0b74633..0db6ac9036 100644 --- a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf +++ b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf index f80ce3751a..84cb18d435 100644 --- a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf index f61039ff17..270ad75845 100644 --- a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf +++ b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index 9d64ae1976..f6d3e8575a 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -44,7 +44,6 @@ gNBs = local_s_portd = 2152; remote_s_portc = 500; remote_s_portd = 2152; - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf index f95bdf91ae..4309c13dd3 100644 --- a/ci-scripts/conf_files/gNB_SA_DU.conf +++ b/ci-scripts/conf_files/gNB_SA_DU.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( 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 04dc1b1373..49383072ed 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 @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; 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 fd52c7fed5..610485fc92 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 @@ -38,7 +38,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf index dcb3dd89b7..24ec8f17f8 100644 --- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf index 1019ec75ad..b3c7d7d1da 100644 --- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf index 03155b85d8..c668601c06 100644 --- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" 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 5e6b3fb217..92c3a7a2e9 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 @@ -41,7 +41,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" do_SRS = 1; 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 09d9b50335..672713d504 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 @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" 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 18ca7b5d1e..5bd8b26e05 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 @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" do_SRS = 1; 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 9e1f499f03..e1264bd069 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 @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; #pusch_TargetSNRx10 = 200; #pucch_TargetSNRx10 = 200; ul_prbblacklist = "51,52,53,54" 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 42fc89b2ed..f92242138c 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 @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; #pusch_TargetSNRx10 = 200; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 835e334bbb..9334f2cf59 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index f3515d3882..cd3ab6278e 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf index 8f480d3757..371753eccc 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf @@ -20,7 +20,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf index b78ca916f3..6b7122341d 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -32,8 +32,8 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; + enable_sdap = 1; pdcch_ConfigSIB1 = ( { diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf new file mode 100644 index 0000000000..2a6053ab46 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -0,0 +1,344 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 222; + mnc = 01; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + #sd = 0x1; // 0 false, else true + } + ); + + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + min_rxtxtime = 2; + do_CSIRS = 1; + do_SRS = 1; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + +# Dedicated Serving Cell Configuration +servingCellConfigDedicated = ({ + # BWP-Downlink + # BWP 1 Configuration + dl_bwp-Id_1 = 1; + dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp1_subcarrierSpacing = 1; + + # BWP 2 Configuration + dl_bwp-Id_2 = 2; + dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp2_subcarrierSpacing = 1; + + # BWP 3 Configuration + dl_bwp-Id_3 = 3; + dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp3_subcarrierSpacing = 1; + + firstActiveDownlinkBWP-Id = 1; #BWP-Id + defaultDownlinkBWP-Id = 1; #BWP-Id + + # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, + # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, + # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, + # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + + # UplinkConfig + # BWP-Uplink + # BWP 1 Configuration + ul_bwp-Id_1 = 1; + ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp1_subcarrierSpacing = 1; + + # BWP 2 Configuration + ul_bwp-Id_2 = 2; + ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp2_subcarrierSpacing = 1; + + # BWP 3 Configuration + ul_bwp-Id_3 = 3; + ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp3_subcarrierSpacing = 1; + + firstActiveUplinkBWP-Id = 1; #BWP-Id + } +); + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "172.21.16.136"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.137/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.137/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + ulsch_max_frame_inactivity = 0; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 10; + att_rx = 10; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; +} +); + +THREAD_STRUCT = ( +{ + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; +} +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf index bd3076a014..ad1471339a 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; sib1_tda = 15; min_rxtxtime = 6; diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 0e0afefaaf..9113d29ac9 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -311,6 +311,8 @@ class EPCManagement(): tmp = str(response[0],'utf-8') self.MmeIPAddress = tmp.rstrip() logging.debug('AMF IP Address ' + self.MmeIPAddress) + else: + logging.error('no container with name oai-amf found, could not retrieve AMF IP address') mySSH.close() def CheckHSSProcess(self, status_queue): diff --git a/ci-scripts/main.py b/ci-scripts/main.py index adef885942..baed6a6011 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -102,7 +102,7 @@ def AssignParams(params_dict): def GetParametersFromXML(action): - if action == 'Build_eNB' or action == 'Build_Image': + if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy': RAN.Build_eNB_args=test.findtext('Build_eNB_args') CONTAINERS.imageKind=test.findtext('kind') forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') @@ -138,6 +138,9 @@ def GetParametersFromXML(action): RAN.backgroundBuild=True else: RAN.backgroundBuild=False + proxy_commit = test.findtext('proxy_commit') + if proxy_commit is not None: + CONTAINERS.proxyCommit = proxy_commit elif action == 'WaitEndBuild_eNB': RAN.Build_eNB_args=test.findtext('Build_eNB_args') @@ -915,10 +918,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML=ldpc.Run_PhySim(HTML,CONST,id) elif action == 'Build_Image': CONTAINERS.BuildImage(HTML) + elif action == 'Build_Proxy': + CONTAINERS.BuildProxy(HTML) elif action == 'Copy_Image_to_Test': CONTAINERS.Copy_Image_to_Test_Server(HTML) elif action == 'Deploy_Object': CONTAINERS.DeployObject(HTML, EPC) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True elif action == 'Undeploy_Object': CONTAINERS.UndeployObject(HTML, RAN) elif action == 'Cppcheck_Analysis': diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 680763d247..a576054370 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -374,7 +374,7 @@ class RANManagement(): mySSH.open(lIpAddr, lUserName, lPassWord) eth_interface = 'any' fltr = 'sctp' - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') + logging.debug('\u001B[1m Launching tshark on xNB on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') pcapfile = pcapfile_prefix + self.testCase_id + '_log.pcap' mySSH.command('echo ' + lPassWord + ' | sudo -S rm -f /tmp/' + pcapfile , '\$', 5) mySSH.command('echo $USER; nohup sudo -E tshark -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + pcapfile + ' > /dev/null 2>&1 &','\$', 5) @@ -390,7 +390,7 @@ class RANManagement(): mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) eth_interface = 'any' fltr = 'sctp' - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') + logging.debug('\u001B[1m Launching tshark on EPC on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') self.epcPcapFile = 'enb_' + self.testCase_id + '_s1log.pcap' mySSH.command('echo ' + localEpcPassword + ' | sudo -S rm -f /tmp/' + self.epcPcapFile , '\$', 5) mySSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + self.epcPcapFile + ' > /tmp/tshark.log 2>&1 &', localEpcUserName, 5) @@ -517,7 +517,7 @@ class RANManagement(): localEpcUserName = EPC.UserName localEpcPassword = EPC.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') + logging.debug('\u001B[1m Stopping tshark on EPC \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) if self.epcPcapFile != '': mySSH.command('echo ' + localEpcPassword + ' | sudo -S chmod 666 /tmp/' + self.epcPcapFile, '\$', 5) @@ -644,18 +644,16 @@ class RANManagement(): time.sleep(5) mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) #stopping tshark (valid if eNB and enabled in xml, will not harm otherwise) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') + logging.debug('\u001B[1m Stopping tshark on xNB \u001B[0m') mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) mySSH.close() - # If tracer options is on, stopping tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if (result is not None): + if EPC.IPAddress != "none" and EPC.IPAddress != '': localEpcIpAddr = EPC.IPAddress localEpcUserName = EPC.UserName localEpcPassword = EPC.Password + logging.debug('\u001B[1m Stopping tshark on EPC (' + localEpcIpAddr + ') \u001B[0m') mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) if self.epcPcapFile != '': diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py index dca3daa817..035da71426 100644 --- a/ci-scripts/sshconnection.py +++ b/ci-scripts/sshconnection.py @@ -60,7 +60,7 @@ class SSHConnection(): count = 0 connect_status = False while count < 4: - self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=no {}@{}'.format(username,ipaddress)) + self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=yes {}@{}'.format(username,ipaddress)) # Longer timeout at connection due to asterix slowness self.ssh.timeout = 25 self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) @@ -84,14 +84,11 @@ class SSHConnection(): else: logging.debug('self.sshresponse = ' + str(self.sshresponse)) elif self.sshresponse == 2: - # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', prompt, 5) - result = re.search(str(ipaddress), str(self.ssh.before)) - if result is None: - self.close() - else: - count = 10 - connect_status = True + # We directly ended up on the remote server because of pubkey auth + count = 10 + connect_status = True + # this expect() seems to be necessary to advance the read buffer until the prompt, or getBefore() will not return the last command + self.sshresponse = self.ssh.expect([prompt]) else: # debug output logging.debug(str(self.ssh.before)) @@ -272,4 +269,4 @@ class SSHConnection(): sys.exit('SCP failed') def getBefore(self): - return str(self.ssh.before) + return self.ssh.before.decode('utf-8') diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index b305aff424..2c5f04b11f 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -1,3 +1,4 @@ + - Build_Proxy - Build_PhySim - Run_PhySim - Build_eNB diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 05b20afed3..61157f72df 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-f1 - Testing 5G NR RF sim in containers - CU-DU F1 split + CU-DU F1 split wrench 100021 diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml b/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml index ac3f7347ba..bb640381cf 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-down-f1 - CleanUp 5G RF - CU-DU F1 split + CleanUp CU-DU F1 split trash 100022 diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index b41dafb767..9564b24b35 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-fdd - Testing 5G NR RF sim - Monolithic FDD gNB + Monolithic FDD gNB with SDAP wrench 4 diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml index d960949f7d..12648ca750 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-fdd-down - CleanUp 5G RF - Monolithic FDD gNB + CleanUp Monolithic FDD gNB with SDAP trash 100012 diff --git a/ci-scripts/xml_files/container_5g_l2sim_proxy.xml b/ci-scripts/xml_files/container_5g_l2sim_proxy.xml new file mode 100644 index 0000000000..af1715d793 --- /dev/null +++ b/ci-scripts/xml_files/container_5g_l2sim_proxy.xml @@ -0,0 +1,42 @@ + + + l2sim-5gnr-proxy-build + Build L2sim proxy image + wrench + 1 + + 000001 + + + + + Build_Proxy + Build L2sim Proxy Image + 1 + 1 + True + 56cfdc0 + + + diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index a1f50948a5..653e1e6513 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-tdd - Testing 5G NR RF sim - Monolithic TDD gNB + Monolithic TDD gNB wrench 4 diff --git a/ci-scripts/xml_files/container_5g_rfsim_down.xml b/ci-scripts/xml_files/container_5g_rfsim_down.xml index b369b1fad8..028ff61864 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_down.xml @@ -22,7 +22,7 @@ --> rfsim-5gnr-down - CleanUp 5G RF - Monolithic TDD gNB + CleanUp Monolithic TDD gNB trash 100002 diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index 8d04be3efd..51e6668cf0 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -53,7 +53,6 @@ Initialize_UE Initialize Quectel idefix - yes diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml new file mode 100644 index 0000000000..7f0475629d --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -0,0 +1,168 @@ + + + TEST-SA-FR1-B200 + SA SanityCheck with QUECTEL + tasks + 1 + + 010002 + 030000 + 030101 + 000001 + 010000 + 000001 + 050000 + 050001 + 010002 + 000001 + 030201 + + + + + + Initialize_UE + Initialize Quectel + idefix + + + + + Terminate_UE + Terminate Quectel + idefix + + + + Copy_Image_to_Test + Copy gNB image to test server + oai-gnb + 1 + 0 + + + + Deploy_Object + Deploy gNB (TDD/Band78/40MHz/B200) in a container + ci-scripts/yaml_files/sa_b200_gnb + 0 + 0 + + + + IdleSleep + Sleep + 5 + + + + IdleSleep + Sleep + 20 + + + + + Ping + Ping: 20pings in 20sec + idefix + -c 20 + 1 + 15 + + + + Ping + Ping: 100pings in 20sec + idefix + -c 100 -i 0.2 + 1 + 15 + + + + Ping + Ping: 20pings in 20sec + idefix + -c 20 + 1 + 15 + + + + Ping + Ping: 100pings in 20sec + idefix + -c 100 -i 0.2 + 1 + 15 + + + + Iperf + iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile) + -u -b 125M -t 60 -i 1 -fm + DL + idefix + 25 + 80 + single-ue + + + + Iperf + iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) + -u -b 8M -t 60 -i 1 -fm + UL + idefix + 1 + 95 + single-ue + + + + Iperf + iperf (BIDIR TCP)(10 sec)(single-ue profile) + -t 10 --bidir + BIDIR + idefix + single-ue + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_b200_gnb + 0 + 0 + + + + diff --git a/ci-scripts/xml_files/container_sa_b200_terminate.xml b/ci-scripts/xml_files/container_sa_b200_terminate.xml new file mode 100644 index 0000000000..5a2b6bd454 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_terminate.xml @@ -0,0 +1,42 @@ + + + TEST-SA-FR1-B200-terminate + SA tear-down in case of problem + tasks + 1 + + 030201 + + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_b200_gnb + 1 + 1 + sa-test + + + diff --git a/ci-scripts/xml_files/fr1_5gc_closure.xml b/ci-scripts/xml_files/fr1_5gc_closure.xml new file mode 100644 index 0000000000..e5e57fa694 --- /dev/null +++ b/ci-scripts/xml_files/fr1_5gc_closure.xml @@ -0,0 +1,37 @@ + + + 5gc-closure + 5GC-Closure + log-out + +060000 + + + + + Terminate_5GCN + Terminate 5GC + + + diff --git a/ci-scripts/xml_files/fr1_5gc_start.xml b/ci-scripts/xml_files/fr1_5gc_start.xml new file mode 100644 index 0000000000..8758b761cd --- /dev/null +++ b/ci-scripts/xml_files/fr1_5gc_start.xml @@ -0,0 +1,38 @@ + + + 5gc-start-tab + 5GC-Start + log-in + + 000100 + + + + + + Initialize_5GCN + Initialize 5GC + + + diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml index 2ef2b7d7ce..459a16c323 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 030000 040000 000002 diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml index 335fe873a1..c8e0659330 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 031000 041000 000002 diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml index a7fd0fc0d7..c72c61c0a2 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 030000 040000 000002 diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml index 2b215479c2..fd983d8835 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 040000 000002 010000 diff --git a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml index 23eaccfcfd..f426bd6035 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 042000 000002 010000 diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml index 603f3f919b..48a9b60e7d 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml @@ -26,6 +26,7 @@ tasks 1 + 011002 041000 000002 011000 diff --git a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml index 0d18a52839..b6388eede2 100644 --- a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml +++ b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 030000 000002 010000 diff --git a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml index f84691ab48..99c8f75e06 100644 --- a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml +++ b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml @@ -26,6 +26,7 @@ tasks 1 + 010002 030001 000002 010000 diff --git a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml new file mode 100644 index 0000000000..9ea52c1247 --- /dev/null +++ b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml @@ -0,0 +1,44 @@ +version: '3.8' + +services: + gnb_mono_tdd: + image: oai-gnb:latest + privileged: true + container_name: sa-b200-gnb + environment: + USE_SA_TDD_MONO_B2XX: 'yes' + USE_B2XX: 'yes' + GNB_NAME: gNB-in-docker + MCC: '222' + MNC: '01' + MNC_LENGTH: 2 + TAC: 1 + NSSAI_SST: 1 + NSSAI_SD0: 1 + AMF_IP_ADDRESS: 172.21.16.136 + GNB_NGA_IF_NAME: eth0 + GNB_NGA_IP_ADDRESS: 192.168.68.194 + GNB_NGU_IF_NAME: eth0 + GNB_NGU_IP_ADDRESS: 192.168.68.194 + USE_ADDITIONAL_OPTIONS: --sa -E -q --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function + volumes: + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.68.194 + #entrypoint: /bin/bash -c "sleep infinity" + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + public_net: + name: sa-b200-gnb-net + ipam: + config: + - subnet: 192.168.68.192/26 + driver_opts: + com.docker.network.bridge.name: "sa-gnb-net" diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c763c8950d..429d14ff54 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -274,6 +274,12 @@ if (SANITIZE_ADDRESS) # wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead. endif () +add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)") +if (SANITIZE_UNDEFINED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") +endif () + add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### @@ -331,13 +337,9 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") # Debug related options ######################################### -add_boolean_option(ASN_EMIT_DEBUG False "ASN1 coder/decoder Debug") -add_boolean_option(ASN_THREAD_SAFE True "ASN1 coder/decoder Debug") -add_boolean_option(MSG_PRINT True "print debug messages") +add_boolean_option(DEBUG_ASN1C False "ASN1 coder/decoder Debug traces, see common/utils/config.h, the logs are regular OAI logs, in the log group 'ASN'") add_boolean_option(DISABLE_XER_PRINT False "print XER Format") add_boolean_option(XER_PRINT False "print XER Format") -add_boolean_option(RRC_MSG_PRINT False "print RRC messages") -add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log") add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace @@ -355,6 +357,12 @@ add_library(ITTI ) add_dependencies(ITTI rrc_flag) +# asn1c skeletons have hardcoded this flag to make customized debug logs +# OAI uses this feature to re-use OAI LOG_I(ASN, ...) +if (DEBUG_ASN1C) + add_definitions(-DHAVE_CONFIG_H) +endif() + ################################################## # ASN.1 grammar C code generation & dependencies # ################################################## @@ -864,7 +872,6 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE") -add_boolean_option(ITTI_SIM False "enable itti simulator") ######################## # Include order @@ -1829,7 +1836,15 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c + #hack: include these files to compile the nr phy simulators + #these files should not be here, will be removed at some point when the + #computation is done directly inside nr_pdcp_integrity_nia1.c instead + #of reusing code of osa_stream_eia.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_rijndael.c ) set(NR_SDAP_SRC @@ -1883,6 +1898,8 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c + ${NR_RRC_DIR}/mac_rrc_dl_direct.c + ${NR_RRC_DIR}/mac_rrc_dl_f1ap.c ${NR_RRC_DIR}/nr_rrc_config.c ${NR_RRC_DIR}/rrc_gNB_nsa.c ${NR_RRC_DIR}/rrc_gNB_internode.c @@ -1961,6 +1978,9 @@ set (MAC_NR_SRC ${NR_GNB_MAC_DIR}/gNB_scheduler_uci.c ${NR_GNB_MAC_DIR}/gNB_scheduler_srs.c ${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c + ${NR_GNB_MAC_DIR}/mac_rrc_dl_handler.c + ${NR_GNB_MAC_DIR}/mac_rrc_ul_direct.c + ${NR_GNB_MAC_DIR}/mac_rrc_ul_f1ap.c ) @@ -1977,6 +1997,7 @@ set (MAC_SRC_UE set (MAC_NR_SRC_UE ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c + ${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c ${NR_UE_MAC_DIR}/config_ue.c ${NR_UE_MAC_DIR}/mac_vars.c ${NR_UE_MAC_DIR}/main_ue_nr.c @@ -3049,7 +3070,7 @@ if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-uesoftmodem nr-softmodem - nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test @@ -3135,50 +3156,6 @@ add_executable(rb_tool ) target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/) -# nr-ittisim -################################################### - -add_executable(nr-ittisim - ${rrc_h} - ${nr_rrc_h} - ${OPENAIR2_DIR}/GNB_APP/gnb_app.c - ${OPENAIR2_DIR}/GNB_APP/gnb_config.c - ${OPENAIR_DIR}/executables/nr-gnb.c - ${OPENAIR_DIR}/executables/nr-ru.c - ${OPENAIR2_DIR}/SIMULATION/NR_RRC/itti_sim.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 - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${OPENAIR_DIR}/common/utils/lte/ue_power.c - ${OPENAIR_DIR}/common/utils/lte/prach_utils.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c - ${XFORMSINTERFACE_SOURCE} - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-ittisim - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA - ITTI ${FLPT_MSG_LIB} ${FLEXRAN_AGENT_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB - NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${FSPT_MSG_LIB} - PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE - -Wl,--end-group z dl) - -target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-ittisim pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) -target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-ittisim ${T_LIB}) - -add_dependencies( nr-ittisim ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) - # ??? #################### list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 61b5b8ba95..88654ac9b5 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1062,7 +1062,8 @@ (Test3: PBCH-only, 217 PRB), (Test4: PBCH and synchronization, 217 RPB), (Test5: PBCH-only, 273 PRB), - (Test6: PBCH and synchronization, 273 PRB) + (Test6: PBCH and synchronization, 273 PRB), + (Test7: PBCH and synchronization, 106PBR, SSB SC OFFSET 6) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1074,8 +1075,9 @@ -s-11 -S-8 -n10 -R217 -s-11 -S-8 -n10 -o8000 -I -R217 -s-11 -S-8 -n10 -R273 - -s-11 -S-8 -n10 -o8000 -I -R273 - nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6 + -s-11 -S-8 -n10 -o8000 -I -R273 + -s-11 -S-8 -n10 -R106 -O6 + nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6 nr_pbchsim.test7 PBCH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 5a201fcfef..09029c285a 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -171,10 +171,12 @@ Options: Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes --ninja Tell cmake to use the Ninja build system. Without, will generate make files +--sanitize + Shortcut for usage of --sanitize-address --sanitize-undefined --sanitize-address | -fsanitize=address - Enable the address sanitizer on all targets ---ittiSIM - Makes the itti simulator + Enable the address sanitizer on all targets +--sanitize-undefined | -fsanitize=undefined + Enable the undefined behavior sanitizer on all targets -h | --help Print this help @@ -451,14 +453,15 @@ function main() { CMAKE_CMD="$CMAKE_CMD -GNinja" MAKE_CMD=ninja shift;; + --sanitize) + CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True -DSANITIZE_UNDEFINED=True" + shift;; --sanitize-address | -fsanitize=address) grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt" CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True" shift;; - --ittiSIM) - ittiSIM=1 - CMAKE_CMD="$CMAKE_CMD -DITTI_SIM=True" - echo_info "Will compile itti simulator" + --sanitize-undefined | -fundefined=address) + CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True" shift;; -h | --help) print_help @@ -613,9 +616,6 @@ function main() { if [ "$nrUE" = 1 ] ; then execlist="$execlist nr-uesoftmodem" fi - if [ "$ittiSIM" = "1" ] ; then - execlist="$execlist nr-ittisim" - fi if [[ "$execlist" == "" && "$SIMUS_PHY" != "1" ]]; then echo_success "installing dependencies successful" diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 179e2de428..d35f90fcce 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -109,6 +109,7 @@ check_supported_distribution() { "ubuntu18.04") return 0 ;; "ubuntu16.04") return 0 ;; "fedora35") return 0 ;; + "fedora36") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; "rhel7.7") return 0 ;; @@ -196,8 +197,8 @@ check_warnings() { #argument: # $1: log file check_errors() { - #we look for 'warning:' in the compilation log file - error_count=`grep "error:" "$1" | wc -l` + #we look for 'error:' in the compilation log file + error_count=`grep -c "error:" "$1"` if [ $error_count -gt 0 ]; then echo_error "ERROR: $error_count error. See $1" fi @@ -623,7 +624,6 @@ check_install_additional_tools (){ android-tools-adb \ wvdial \ sshpass \ - nscd \ bc \ ntp" elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then @@ -648,7 +648,6 @@ check_install_additional_tools (){ wvdial \ numpy \ sshpass \ - nscd \ python2-paramiko \ python-pyroute2 \ python-netifaces \ @@ -676,7 +675,6 @@ check_install_additional_tools (){ wvdial \ python-numpy \ sshpass \ - nscd \ python-paramiko \ python-pyroute2 \ python-netifaces \ diff --git a/common/utils/collection/linear_alloc.h b/common/utils/collection/linear_alloc.h new file mode 100644 index 0000000000..ac8a305ff6 --- /dev/null +++ b/common/utils/collection/linear_alloc.h @@ -0,0 +1,71 @@ +/* + * 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 + */ + +#ifndef LINEAR_ALLOC_H +#define LINEAR_ALLOC_H + +#include + +typedef unsigned int uid_t; +#define UID_LINEAR_ALLOCATOR_SIZE 1024 +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((UID_LINEAR_ALLOCATOR_SIZE/8)/sizeof(unsigned int)) + 1) +typedef struct uid_linear_allocator_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; +} uid_allocator_t; + +static inline void uid_linear_allocator_init(uid_allocator_t *uia) { + memset(uia, 0, sizeof(uid_allocator_t)); +} + +static inline uid_t uid_linear_allocator_new(uid_allocator_t *uia) { + unsigned int bit_index = 1; + uid_t uid = 0; + + for (unsigned int i = 0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { + if (uia->bitmap[i] != UINT_MAX) { + bit_index = 1; + uid = 0; + + while ((uia->bitmap[i] & bit_index) == bit_index) { + bit_index = bit_index << 1; + uid += 1; + } + + uia->bitmap[i] |= bit_index; + return uid + (i*sizeof(unsigned int)*8); + } + } + + return UINT_MAX; +} + + +static inline void uid_linear_allocator_free(uid_allocator_t *uia, uid_t uid) { + const unsigned int i = uid/sizeof(unsigned int)/8; + const unsigned int bit = uid % (sizeof(unsigned int) * 8); + const unsigned int value = ~(1 << bit); + + if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { + uia->bitmap[i] &= value; + } +} + +#endif /* LINEAR_ALLOC_H */ diff --git a/common/utils/config.h b/common/utils/config.h new file mode 100644 index 0000000000..597ead7ed6 --- /dev/null +++ b/common/utils/config.h @@ -0,0 +1,56 @@ +/* + * 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 + */ + +#ifndef UTILS_CONFIG_H_ASN1 +#define UTILS_CONFIG_H_ASN1 + +// This is hard coded file name "config.h" and HAVE_CONFIG_H_ in asn1c skeletons + +/* + * This file "config.h" will be used by asn1c if HAVE_CONFIG_H_ is defined and + * included. This logs asn1c encoder and decoder traces at execution time using + * the regular OAI logging system, i.e., LOG_I(ASN...); + * + * As it is very verbose, note that you can change the log level per module in + * source or in gdb, e.g., to only activate it for a short time. + * + * In code: + * ``` + * set_log(ASN, OAI_INFO); // enable logging + * // do your encoding here + * set_log(ASN, OAI_ERR); // disable logging + * ``` + * + * in gdb: + * ``` + * gdb> p set_log(ASN, 1) // disable log, 1 == OAI_ERR + * gdb> p set_log(ASN, 5) // enable log, 5 == OAI_INFO + * ``` + */ + +#include "common/utils/LOG/log.h" +#if DEBUG_ASN1C +#define ASN_DEBUG(x...) do{ LOG_I(ASN,x);LOG_I(ASN,"\n"); } while(false) +#else +#define ASN_DEBUG(x...) +#endif + +#endif /* UTILS_CONFIG_H_ASN1 */ diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 6add03c324..0fb4824d42 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -472,6 +472,236 @@ int get_subband_size(int NPRB,int size) { } +void get_samplerate_and_bw(int mu, + int n_rb, + int8_t threequarter_fs, + double *sample_rate, + unsigned int *samples_per_frame, + double *tx_bw, + double *rx_bw) { + + if (mu == 0) { + switch(n_rb) { + case 270: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 50e6; + *rx_bw = 50e6; + } else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + case 216: + if (threequarter_fs) { + *sample_rate=46.08e6; + *samples_per_frame = 460800; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + break; + case 160: //30 MHz + case 133: //25 MHz + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + case 106: + if (threequarter_fs) { + *sample_rate=23.04e6; + *samples_per_frame = 230400; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + break; + case 52: + if (threequarter_fs) { + *sample_rate=11.52e6; + *samples_per_frame = 115200; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + else { + *sample_rate=15.36e6; + *samples_per_frame = 153600; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + case 25: + if (threequarter_fs) { + *sample_rate=5.76e6; + *samples_per_frame = 57600; + *tx_bw = 5e6; + *rx_bw = 5e6; + } + else { + *sample_rate=7.68e6; + *samples_per_frame = 76800; + *tx_bw = 5e6; + *rx_bw = 5e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else if (mu == 1) { + switch(n_rb) { + + case 273: + if (threequarter_fs) { + *sample_rate=184.32e6; + *samples_per_frame = 1843200; + *tx_bw = 100e6; + *rx_bw = 100e6; + } else { + *sample_rate=122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 100e6; + *rx_bw = 100e6; + } + break; + case 217: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 80e6; + *rx_bw = 80e6; + } else { + *sample_rate=122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 80e6; + *rx_bw = 80e6; + } + break; + case 162 : + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 60e6; + *rx_bw = 60e6; + } + + break; + + case 133 : + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + + break; + case 106: + if (threequarter_fs) { + *sample_rate=46.08e6; + *samples_per_frame = 460800; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + break; + case 51: + if (threequarter_fs) { + *sample_rate=23.04e6; + *samples_per_frame = 230400; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + break; + case 24: + if (threequarter_fs) { + *sample_rate=11.52e6; + *samples_per_frame = 115200; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + else { + *sample_rate=15.36e6; + *samples_per_frame = 153600; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else if (mu == 3) { + switch(n_rb) { + case 66: + if (threequarter_fs) { + *sample_rate=184.32e6; + *samples_per_frame = 1843200; + *tx_bw = 100e6; + *rx_bw = 100e6; + } else { + *sample_rate = 122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 100e6; + *rx_bw = 100e6; + } + + break; + + case 32: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 50e6; + *rx_bw = 50e6; + } else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + + break; + + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else { + AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); + } +} + // from start symbol index and nb or symbols to symbol occupation bitmap in a slot uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) { return ((1< #include -#ifdef ITTI_SIM - #include -#endif - /* static const char *const messages_definition_xml = { #include @@ -308,9 +304,11 @@ void *rrc_enb_process_msg(void *); TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MAC_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\ diff --git a/common/utils/time_meas.h b/common/utils/time_meas.h index fded7f1a9c..eb81d09434 100644 --- a/common/utils/time_meas.h +++ b/common/utils/time_meas.h @@ -62,7 +62,7 @@ typedef struct time_stats { oai_cputime_t in; /*!< \brief time at measure starting point */ oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/ oai_cputime_t p_time; /*!< \brief absolute process duration */ - oai_cputime_t diff_square; /*!< \brief process duration square */ + double diff_square; /*!< \brief process duration square */ oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/ int trials; /*!< \brief number of start point - end point iterations */ int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */ @@ -156,7 +156,7 @@ static inline void stop_meas(time_stats_t *ts) { ts->diff += (out-ts->in); /// process duration is the difference between two clock points ts->p_time = (out-ts->in); - ts->diff_square += (out-ts->in)*(out-ts->in); + ts->diff_square += ((double)out-ts->in)*((double)out-ts->in); if ((out-ts->in) > ts->max) ts->max = out-ts->in; diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index d0856b415d..5db6e44d8d 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -440,6 +440,10 @@ The following features are valid for the gNB and the 5G-NR UE. - PTRS support - Support for 1, 2 and 4 RX antennas - Support for up to 2 layers (currently limited to DMRS configuration type 2) +* Measurements based on NR-CSIRS + - RI, PMI and CQI computation + - Support for 1 and 2 RX antennas + - Support for up to 2 layers * NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). - PUSCH mapping type A and B - DMRS configuration type 1 and 2 @@ -488,12 +492,15 @@ The following features are valid for the gNB and the 5G-NR UE. * UCI processing - ACK/NACK processing - Triggering periodic SR - - CSI measurement reporting (SSB RSRP only) -* DLSH scheduler + - CSI measurement reporting +* DLSCH scheduler - Configuration of fapi PDU according to DCI - HARQ procedures * ULSCH scheduler - Configuration of fapi PDU according to DCI +* NR-CSIRS scheduler + - Scheduling of NR-CSIRS reception + - Fill UCI for CSI measurement reporting * Scheduler procedures for SRS transmission - Periodic SRS transmission * Bandwidth part (BWP) operation diff --git a/doc/ITTISIM.md b/doc/ITTISIM.md deleted file mode 100755 index 13fdd90846..0000000000 --- a/doc/ITTISIM.md +++ /dev/null @@ -1,48 +0,0 @@ - - - - - -
- - - - - - Running L3 ITTI simulator -
- -This page is valid on the following branches: - -- `develop` starting from tag `2020.w48` - -# 1. Building the ITTI simulator. - -The ITTI simulator is available directly from the standard build. - -```bash -$ source oaienv -$ cd cmake_targets -$ sudo ./build_oai -x -w None -c -ittiSIM -``` - -# 2. Running the ITTI simulator. - -The ITTI simulator establishes ITTI-threaded communication between the gNB RRC task and the UE RRC task. - -This allows to test the sequence of NGAP/RRC/NAS messages. - -The main limitations are: - -- NAS is a simple stub that just sends and receives messages -- only initial Attach sequence - -## 2.1. Starting the ITTI simulator - -The ITTI simulator is able to run with a connected 5GC or without any. -The develop branch tag `2020.w48` only works RRC without 5GC connection. - -```bash -$ sudo -E ./ran_build/build/nr-ittisim -O gnb.conf -``` - diff --git a/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md index 1110a5bc6c..fc0700c699 100644 --- a/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md +++ b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md @@ -71,10 +71,6 @@ reboot # https://docs.docker.com/compose/install/ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose - -docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net -sudo service docker restart - ``` ## 2.2 OAI CN5G Setup @@ -82,39 +78,36 @@ sudo service docker restart ```bash # Git oai-cn5g-fed repository git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed -cd ~/oai-cn5g-fed -git checkout master -./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop +# Pull docker images docker pull oaisoftwarealliance/oai-amf:develop docker pull oaisoftwarealliance/oai-nrf:develop docker pull oaisoftwarealliance/oai-smf:develop docker pull oaisoftwarealliance/oai-udr:develop docker pull oaisoftwarealliance/oai-udm:develop docker pull oaisoftwarealliance/oai-ausf:develop -docker pull oaisoftwarealliance/oai-upf-vpp:develop docker pull oaisoftwarealliance/oai-spgwu-tiny:develop -docker pull oaisoftwarealliance/oai-nssf:develop +docker pull oaisoftwarealliance/trf-gen-cn5g:latest +# Tag docker images docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop -docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop -docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest ``` ## 2.3 OAI CN5G Configuration files -Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: -- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) -- [oai_db.sql](tutorial_resources/oai_db.sql) +Download and copy configuration files: +- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose` +- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database` Change permissions on oai_db.sql to prevent mysql permission denied error: ```bash -chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql ``` ## 2.4 SIM Card @@ -175,7 +168,7 @@ cd cmake_targets ```bash cd ~/oai-cn5g-fed/docker-compose -python3 core-network.py --type start-basic --fqdn yes --scenario 1 +python3 core-network.py --type start-basic --scenario 1 ``` ## 4.2 Run OAI gNB diff --git a/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md index ed917e09ea..d68057fd08 100644 --- a/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md +++ b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md @@ -72,10 +72,6 @@ reboot # https://docs.docker.com/compose/install/ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose - -docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net -sudo service docker restart - ``` ## 2.2 OAI CN5G Setup @@ -83,39 +79,36 @@ sudo service docker restart ```bash # Git oai-cn5g-fed repository git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed -cd ~/oai-cn5g-fed -git checkout master -./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop +# Pull docker images docker pull oaisoftwarealliance/oai-amf:develop docker pull oaisoftwarealliance/oai-nrf:develop docker pull oaisoftwarealliance/oai-smf:develop docker pull oaisoftwarealliance/oai-udr:develop docker pull oaisoftwarealliance/oai-udm:develop docker pull oaisoftwarealliance/oai-ausf:develop -docker pull oaisoftwarealliance/oai-upf-vpp:develop docker pull oaisoftwarealliance/oai-spgwu-tiny:develop -docker pull oaisoftwarealliance/oai-nssf:develop +docker pull oaisoftwarealliance/trf-gen-cn5g:latest +# Tag docker images docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop -docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop -docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest ``` ## 2.3 OAI CN5G Configuration files -Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: -- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) -- [oai_db.sql](tutorial_resources/oai_db.sql) +Download and copy configuration files: +- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose` +- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database` Change permissions on oai_db.sql to prevent mysql permission denied error: ```bash -chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql ``` ## 2.4 SIM Card @@ -193,7 +186,7 @@ The following steps are recommended. Please change the network interface(s) as r ```bash cd ~/oai-cn5g-fed/docker-compose -python3 core-network.py --type start-basic --fqdn yes --scenario 1 +python3 core-network.py --type start-basic --scenario 1 ``` ## 4.2 Run OAI gNB diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index 547fd5a23b..c6a01f278d 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -9,19 +9,19 @@ | Machine | IP address | Lockable Resource | Function | Connected devices | | ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- | -| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB | 173.21.19.14 | -| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB, UE (5G) | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) | +| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB (n78) | 173.21.19.14 | +| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) | | porcepix | 172.21.16.136 | CI-NSA-MiniBench | Executor, EPC, 5GC | -- | | nrmodule2 | 172.21.16.139 | CI-NSA-MiniBench | Quectel | Quectel module | -| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB | B200mini (30C51D4) | +| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB (n78) | B200mini (30C51D4) | | caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) | | idefix | 172.21.16.135 | CI-NSA-MiniBench | Quectel | Quectel module | -| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | TBD | Amarisoft UE simulator | +| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator | | bellatrix | 192.168.117.115 | CI-RAN-VM-Deployment | Executor | -- | | nano | 192.168.12.62 | CI-Bench-1-Phones | EPC, adb | 2x COTS (adb) | | hutch | 192.168.12.19 | CI-Bench-1-Phones | eNB (B7) | B200mini (30C5239) | | starsky | 192.168.12.18 | CI-Bench-1-Phones | eNB (B40) | b200mini (30A3E3C) | -| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE 4G (B) | B200mini (30AE8C9) | +| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE (B7UE) | B200mini (30AE8C9) | Note: The available resources, and their current usage, is indicated here: - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -40,7 +40,7 @@ Note: The available resources, and their current usage, is indicated here: ### OTA Testbench -[Proper image to be followed up. TBD: add antennas/circulators] +**Purpose**: Over-the-air 4G/5G (NSA/SA) tests Note: obelix and porcepix are both used in the OTA testbench and the 5G NSA/Faraday Cage testbench! @@ -89,7 +89,10 @@ Webhook currently only ping - [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/) - obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ ltebox - - basic NSA test, known to be instable + - basic NSA test +- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/) + - obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ sabox + - basic SA test (40 MHz TDD) - [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/) - asterix (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster - unitary simulators (`nr_dlsim`, etc.) diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.pdf b/doc/testbenches_doc_resources/4g-faraday-bench.pdf index 7e31789e9a..f6f7b078e6 100644 Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.pdf and b/doc/testbenches_doc_resources/4g-faraday-bench.pdf differ diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.png b/doc/testbenches_doc_resources/4g-faraday-bench.png index c69065a369..598715a193 100644 Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.png and b/doc/testbenches_doc_resources/4g-faraday-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf index f6d960c1a2..1b921e6437 100644 Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png index c677b598e9..006e6ab347 100644 Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex index 66b52f7f69..a9f12fe3df 100644 --- a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex +++ b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex @@ -30,7 +30,7 @@ \draw (obelix) -- (b210o); \node[above right=0.35cm of faraday.south west] (antn) {\includegraphics[width=0.3cm]{antenna}}; - \draw (b210n) -| node [pos=0.2, duplexer] {B78} (antn); + \draw (b210n) -| node [pos=0.2, duplexer] {n78} (antn); \node[left=5cm of faraday, label=above:porcepix] (porcepix) {\includegraphics[width=1.2cm]{server}}; diff --git a/doc/testbenches_doc_resources/5g-ota-bench.pdf b/doc/testbenches_doc_resources/5g-ota-bench.pdf index e4d4c15e39..121969030e 100644 Binary files a/doc/testbenches_doc_resources/5g-ota-bench.pdf and b/doc/testbenches_doc_resources/5g-ota-bench.pdf differ diff --git a/doc/testbenches_doc_resources/5g-ota-bench.png b/doc/testbenches_doc_resources/5g-ota-bench.png index c93de7ec6f..86ae6b2b64 100644 Binary files a/doc/testbenches_doc_resources/5g-ota-bench.png and b/doc/testbenches_doc_resources/5g-ota-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-ota-bench.tex b/doc/testbenches_doc_resources/5g-ota-bench.tex index cfd0bda22d..c3a524fb0a 100644 --- a/doc/testbenches_doc_resources/5g-ota-bench.tex +++ b/doc/testbenches_doc_resources/5g-ota-bench.tex @@ -21,7 +21,7 @@ edge (porcepix); \node[right=0.3cm of asterix, label=above:N310] (n310a) {\includegraphics[width=1.5cm]{n310}} edge (asterix); - \node[right=.2cm of n310a, duplexer] (b78o) {B78} edge (n310a); + \node[right=.2cm of n310a, duplexer] (b78o) {n78} edge (n310a); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) @@ -32,20 +32,20 @@ edge (porcepix); \node[above right=-0.5cm and 0.3cm of obelix, label=above:N310] (n310o) {\includegraphics[width=1.5cm]{n310}} edge (obelix); - \node[right=.2cm of n310o, duplexer] (b78o) {B40} edge (n310o); + \node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[below right=-0.5cm and 0.3cm of obelix, label=above:X310] (x310o) {\includegraphics[width=1.5cm]{x310}} edge (obelix); - \node[right=.2cm of x310o, duplexer] (b78o) {B78} edge (x310o); + \node[right=.2cm of x310o, duplexer] (b78o) {n78} edge (x310o); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); - \node[right=5.0cm of n310o, label=above:RM500Q-GL] (quectel) + \node[above right=-1.3cm and 5.0cm of n310a.east, label=above:RM500Q-GL] (quectel) {\includegraphics[height=1.2cm]{quectel}}; \node[above left=-0.1cm and 0.8cm of quectel.west] (aq2) {\includegraphics[width=0.3cm]{antenna}} edge (quectel); @@ -59,5 +59,10 @@ {\includegraphics[width=1.2cm]{server}} edge (quectel); + \node[above right=-0.3cm and 5.0cm of x310o.east, label=above:amariue] (amariue) + {\includegraphics[height=1.2cm]{server}}; + \node[left=0.8cm of amariue.west] (aa1) + {\includegraphics[width=0.3cm]{antenna}} edge (amariue); + \end{tikzpicture} \end{document} diff --git a/doc/testing_gnb_w_cots_ue_resources/gnb.conf b/doc/testing_gnb_w_cots_ue_resources/gnb.conf index c96d207445..206e1b4f02 100755 --- a/doc/testing_gnb_w_cots_ue_resources/gnb.conf +++ b/doc/testing_gnb_w_cots_ue_resources/gnb.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { diff --git a/doc/tutorial_resources/docker-compose-basic-nrf.yaml b/doc/tutorial_resources/docker-compose-basic-nrf.yaml index 6750cb78be..cd1e957ad8 100644 --- a/doc/tutorial_resources/docker-compose-basic-nrf.yaml +++ b/doc/tutorial_resources/docker-compose-basic-nrf.yaml @@ -4,8 +4,8 @@ services: container_name: "mysql" image: mysql:5.7 volumes: - - ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql - - ./mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh + - ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ./healthscripts/mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh environment: - TZ=Europe/Paris - MYSQL_DATABASE=oai_db @@ -21,35 +21,45 @@ services: public_net: ipv4_address: 192.168.70.131 oai-udr: - container_name: oai-udr + container_name: "oai-udr" image: oai-udr:develop environment: - TZ=Europe/Paris - INSTANCE=0 - PID_DIRECTORY=/var/run + - UDR_NAME=OAI_UDR - UDR_INTERFACE_NAME_FOR_NUDR=eth0 - UDR_INTERFACE_PORT_FOR_NUDR=80 - UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080 + - USE_HTTP2=no - UDR_API_VERSION=v1 - MYSQL_IPV4_ADDRESS=192.168.70.131 - MYSQL_USER=test - MYSQL_PASS=test + - DB_CONNECTION_TIMEOUT=300 # Reset the connection to the DB after expiring the timeout (in second) currently can't be changed - MYSQL_DB=oai_db - WAIT_MYSQL=120 + - USE_FQDN_DNS=yes + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - mysql + - oai-nrf networks: public_net: ipv4_address: 192.168.70.136 volumes: - - ./udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh + - ./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 + container_name: "oai-udm" image: oai-udm:develop environment: - TZ=Europe/Paris @@ -58,26 +68,33 @@ services: - UDM_NAME=OAI_UDM - SBI_IF_NAME=eth0 - SBI_PORT=80 + - SBI_HTTP2_PORT=8080 + - USE_HTTP2=no - UDM_VERSION_NB=v1 - USE_FQDN_DNS=yes - UDR_IP_ADDRESS=192.168.70.136 - UDR_PORT=80 - UDR_VERSION_NB=v1 - UDR_FQDN=oai-udr + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - oai-udr networks: public_net: ipv4_address: 192.168.70.137 volumes: - - ./udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh + - ./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 + container_name: "oai-ausf" image: oai-ausf:develop environment: - TZ=Europe/Paris @@ -86,18 +103,25 @@ services: - AUSF_NAME=OAI_AUSF - SBI_IF_NAME=eth0 - SBI_PORT=80 + - USE_HTTP2 + - SBI_HTTP2_PORT - USE_FQDN_DNS=yes - UDM_IP_ADDRESS=192.168.70.137 - UDM_PORT=80 - UDM_VERSION_NB=v1 - UDM_FQDN=oai-udm + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - oai-udm networks: public_net: ipv4_address: 192.168.70.138 volumes: - - ./ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh + - ./healthscripts/ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh" interval: 10s @@ -107,9 +131,10 @@ services: container_name: "oai-nrf" image: oai-nrf:develop environment: + - TZ=Europe/Paris - NRF_INTERFACE_NAME_FOR_SBI=eth0 - NRF_INTERFACE_PORT_FOR_SBI=80 - - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=8080 - NRF_API_VERSION=v1 - INSTANCE=0 - PID_DIRECTORY=/var/run @@ -117,7 +142,7 @@ services: public_net: ipv4_address: 192.168.70.130 volumes: - - ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh + - ./healthscripts/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh" interval: 10s @@ -146,9 +171,7 @@ services: - PLMN_SUPPORT_MNC=99 - PLMN_SUPPORT_TAC=0x0001 - SST_0=1 - - SD_0=1 - - SST_1=1 - - SD_1=12 + - SD_0=0x1 - AMF_INTERFACE_NAME_FOR_NGAP=eth0 - AMF_INTERFACE_NAME_FOR_N11=eth0 - SMF_INSTANCE_ID_0=1 @@ -168,22 +191,30 @@ services: - OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3 - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 + - EXTERNAL_NRF=no - NF_REGISTRATION=yes - SMF_SELECTION=yes - USE_FQDN_DNS=yes - EXTERNAL_AUSF=yes + - EXTERNAL_UDM=no + - EXTERNAL_NSSF=no + - USE_HTTP2=no - NRF_API_VERSION=v1 - NRF_FQDN=oai-nrf - AUSF_IPV4_ADDRESS=192.168.70.138 - AUSF_PORT=80 - AUSF_API_VERSION=v1 - AUSF_FQDN=oai-ausf + - UDM_IPV4_ADDRESS=192.168.70.137 + - UDM_PORT=80 + - UDM_API_VERSION=v2 + - UDM_FQDN=oai-udm depends_on: - mysql - oai-nrf - oai-ausf volumes: - - ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh + - ./healthscripts/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh" interval: 10s @@ -212,26 +243,35 @@ services: - AMF_FQDN=oai-amf - UDM_IPV4_ADDRESS=192.168.70.137 - UDM_PORT=80 - - UDM_API_VERSION=v1 + - UDM_API_VERSION=v2 - UDM_FQDN=oai-udm - UPF_IPV4_ADDRESS=192.168.70.134 - UPF_FQDN_0=oai-spgwu - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 - NRF_API_VERSION=v1 - - USE_LOCAL_SUBSCRIPTION_INFO=yes + - USE_LOCAL_SUBSCRIPTION_INFO=yes #Set to yes if SMF uses local subscription information instead of from an UDM + - USE_NETWORK_INSTANCE=no #Set yes if network instance is to be used for given UPF - NRF_FQDN=oai-nrf - REGISTER_NRF=yes - DISCOVER_UPF=yes - USE_FQDN_DNS=yes - - DNN_RANGE1=12.1.1.2 - 12.1.1.128 - - DNN_RANGE0=12.2.1.2 - 12.2.1.128 - - DNN_NI1=oai + - HTTP_VERSION=1 # Default: 1 + - UE_MTU=1500 + - DNN_NI0=oai + - TYPE0=IPv4 + - DNN_RANGE0=12.1.1.2 - 12.1.1.253 + - NSSAI_SST0=1 + - NSSAI_SD0=0x1 + - SESSION_AMBR_UL0=1000Mbps + - SESSION_AMBR_DL0=1000Mbps + - DEFAULT_CSCF_IPV4_ADDRESS=127.0.0.1 # only needed when ims is being used + - ENABLE_USAGE_REPORTING=no # Set yes if UE USAGE REPORTING is to be done at UPF depends_on: - oai-nrf - oai-amf volumes: - - ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh + - ./healthscripts/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh" interval: 10s @@ -258,17 +298,23 @@ services: - MNC03=099 - TAC=1 - GW_ID=1 + - THREAD_S1U_PRIO=80 + - S1U_THREADS=8 + - THREAD_SX_PRIO=81 + - SX_THREADS=1 + - THREAD_SGI_PRIO=80 + - SGI_THREADS=8 - REALM=openairinterface.org - ENABLE_5G_FEATURES=yes - REGISTER_NRF=yes - - USE_FQDN_NRF=no + - USE_FQDN_NRF=yes - UPF_FQDN_5G=oai-spgwu - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 - NRF_API_VERSION=v1 - NRF_FQDN=oai-nrf - NSSAI_SST_0=1 - - NSSAI_SD_0=1 + - NSSAI_SD_0=0x1 - DNN_0=oai depends_on: - oai-nrf @@ -280,7 +326,7 @@ services: - ALL privileged: true volumes: - - ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh + - ./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 @@ -290,12 +336,10 @@ services: public_net: ipv4_address: 192.168.70.134 oai-ext-dn: - image: ubuntu:bionic + image: trf-gen-cn5g:latest privileged: true container_name: oai-ext-dn entrypoint: /bin/bash -c \ - "apt update; apt install -y iptables iproute2 iperf iperf3 iputils-ping;"\ - "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ "ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity" depends_on: - oai-spgwu @@ -303,14 +347,14 @@ services: public_net: ipv4_address: 192.168.70.135 networks: + # public_net: + # external: + # name: demo-oai-public-net public_net: - external: - name: demo-oai-public-net -# public_net: -# driver: bridge -# name: demo-oai-public-net -# ipam: -# config: -# - subnet: 192.168.70.128/26 -# driver_opts: -# com.docker.network.bridge.name: "demo-oai" + driver: bridge + name: demo-oai-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "demo-oai" diff --git a/doc/tutorial_resources/oai_db.sql b/doc/tutorial_resources/oai_db.sql index e019c60e86..fb8f4b20ed 100644 --- a/doc/tutorial_resources/oai_db.sql +++ b/doc/tutorial_resources/oai_db.sql @@ -151,10 +151,13 @@ CREATE TABLE `AuthenticationSubscription` ( -- INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES -('208950000000031', '5G_AKA', '0C0A34601D4F07677303652C0462535B', '0C0A34601D4F07677303652C0462535B', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '63bfa50ee6523365ff14c1f45f88737d', NULL, NULL, NULL, NULL, '208950000000031'); - + ('2089900007487', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '2089900007487'); INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES -('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001'); + ('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001'); +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES + ('208990000000002', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000002'); +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES + ('208990000000003', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000003'); -- -------------------------------------------------------- @@ -203,6 +206,19 @@ CREATE TABLE `SessionManagementSubscriptionData` ( `3gppChargingCharacteristics` varchar(50) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- +-- Dumping data for table `SessionManagementSubscriptionData` +-- + +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('2089900007487', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000001', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000002', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.3\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000003', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.4\"}]}}'); + -- -------------------------------------------------------- -- diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py index 850bb535a5..ec8f32ec6e 100644 --- a/docker/scripts/generateTemplate.py +++ b/docker/scripts/generateTemplate.py @@ -60,6 +60,7 @@ def main(): "rcc.band40.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.tm1.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "gnb.sa.band78.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.sa.band66.fr1.106PRB.usrpn300.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_CU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_DU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index dd6256609c..6deff8da10 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -10,6 +10,7 @@ THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD} if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi +if [[ -v USE_SA_TDD_MONO_B2XX ]]; then cp $PREFIX/etc/gnb.sa.tdd.b2xx.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_FDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.fdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_CU ]]; then cp $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_TDD_CU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi @@ -17,6 +18,10 @@ if [[ -v USE_SA_NFAPI_VNF ]]; then cp $PREFIX/etc/gnb.sa.nfapi.vnf.conf $PREFIX/ # Sometimes, the templates are not enough. We mount a conf file on $PREFIX/etc. It can be a template itself. if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/gnb.conf; fi +# Resolve AMF FQDN +AMF_FQDN=${AMF_FQDN:-oai-amf-svc} +if ($USE_FQDN); then AMF_IP_ADDRESS=(`getent hosts $AMF_FQDN | awk '{print $1}'`); fi + # Only this template will be manipulated CONFIG_FILES=`ls $PREFIX/etc/gnb.conf || true` diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml index d5942f2c9b..420559ff3f 100644 --- a/docker/scripts/gnb_parameters.yaml +++ b/docker/scripts/gnb_parameters.yaml @@ -94,6 +94,36 @@ - key: parallel_config env: "@THREAD_PARALLEL_CONFIG@" + - filePrefix: gnb.sa.band78.fr1.106PRB.usrpb210.conf + outputfilename: "gnb.sa.tdd.b2xx.conf" + config: + - key: Active_gNBs + env: "@GNB_NAME@" + - key: gNB_name + env: "@GNB_NAME@" + - key: mcc + env: "@MCC@" + - key: mnc + env: "@MNC@" + - key: mnc_length + env: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: sst + env: "@NSSAI_SST@" + - key: ipv4 + env: "@AMF_IP_ADDRESS@" + - key: GNB_INTERFACE_NAME_FOR_NG_AMF + env: "@GNB_NGA_IF_NAME@" + - key: GNB_IPV4_ADDRESS_FOR_NG_AMF + env: "@GNB_NGA_IP_ADDRESS@" + - key: GNB_INTERFACE_NAME_FOR_NGU + env: "@GNB_NGU_IF_NAME@" + - key: GNB_IPV4_ADDRESS_FOR_NGU + env: "@GNB_NGU_IP_ADDRESS@" + - key: parallel_config + env: "@THREAD_PARALLEL_CONFIG@" + - filePrefix: gnb.sa.band66.fr1.106PRB.usrpn300.conf outputfilename: "gnb.sa.fdd.conf" config: diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index b51e5b9098..a4070a9482 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -466,7 +466,7 @@ void init_gNB_Tpool(int inst) { pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning } - if (!get_softmodem_params()->emulate_l1) + 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); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ad018b17ab..3ddca74194 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -31,6 +31,7 @@ #undef MALLOC //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 "common/utils/assertions.h" #include "common/utils/system.h" #include "common/ran_context.h" @@ -809,226 +810,13 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (mu == NR_MU_0) { - switch(N_RB) { - case 270: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - case 216: - if (fp->threequarter_fs) { - cfg->sample_rate=46.08e6; - cfg->samples_per_frame = 460800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - break; - case 160: //30 MHz - case 133: //25 MHz - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - case 106: - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - break; - case 52: - if (fp->threequarter_fs) { - cfg->sample_rate=11.52e6; - cfg->samples_per_frame = 115200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - case 25: - if (fp->threequarter_fs) { - cfg->sample_rate=5.76e6; - cfg->samples_per_frame = 57600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } - else { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } - break; - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else if (mu == NR_MU_1) { - switch(N_RB) { - - case 273: - if (fp->threequarter_fs) { - cfg->sample_rate=184.32e6; - cfg->samples_per_frame = 1843200; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - break; - case 217: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } - break; - case 162 : - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 60e6; - cfg->rx_bw = 60e6; - } - - break; - - case 133 : - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - - break; - case 106: - if (fp->threequarter_fs) { - cfg->sample_rate=46.08e6; - cfg->samples_per_frame = 460800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - break; - case 51: - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - break; - case 24: - if (fp->threequarter_fs) { - cfg->sample_rate=11.52e6; - cfg->samples_per_frame = 115200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - break; - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else if (mu == NR_MU_3) { - switch(N_RB) { - case 66: - if (fp->threequarter_fs) { - cfg->sample_rate=184.32e6; - cfg->samples_per_frame = 1843200; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } else { - cfg->sample_rate = 122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - - break; - - case 32: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - - break; - - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else { - AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); - } + get_samplerate_and_bw(mu, + N_RB, + fp->threequarter_fs, + &cfg->sample_rate, + &cfg->samples_per_frame, + &cfg->tx_bw, + &cfg->rx_bw); if (config->cell_config.frame_duplex_type.value==TDD) cfg->duplex_mode = duplex_mode_TDD; diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index e7eda6a612..edf43f9207 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -61,9 +61,6 @@ extern void set_function_spec_param(RU_t *ru); extern void reset_opp_meas(void); extern void print_opp_meas(void); - -extern void init_fep_thread(PHY_VARS_gNB *); - void init_gNB_afterRU(void); extern int stop_L1L2(module_id_t gnb_id); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 01e6c62138..7b39dfdcaa 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -1109,8 +1109,10 @@ void init_NR_UE_threads(int nb_inst) { LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); - pthread_t stat_pthread; - threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW); + if (!IS_SOFTMODEM_NOSTATS_BIT) { + pthread_t stat_pthread; + threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW); + } } } diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index eba5f34691..6229fbbbc2 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -85,6 +85,7 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) { } void get_common_options(uint32_t execmask) { + int32_t stats_disabled = 0; uint32_t online_log_messages=0; uint32_t glog_level=0 ; uint32_t start_telnetsrv = 0, start_telnetclt = 0; @@ -149,6 +150,8 @@ void get_common_options(uint32_t execmask) { if(worker_config != NULL) set_worker_conf(worker_config); nfapi_setmode(nfapi_mode); + if (stats_disabled) + set_softmodem_optmask(SOFTMODEM_NOSTATS_BIT); } void softmodem_printresources(int sig, telnet_printfunc_t pf) { struct rusage usage; diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 0a4a474a6c..3cc248d7af 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -101,6 +101,7 @@ extern "C" #define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n" #define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" #define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n" +#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -171,6 +172,7 @@ extern int usrp_tx_thread; {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ {"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \ {"continuous-tx", CONFIG_HLP_CONTINUOUS_TX,PARAMFLAG_BOOL, iptr:&CONTINUOUS_TX, defintval:0, TYPE_INT, 0}, \ + {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, iptr:&stats_disabled, defintval:0, TYPE_INT, 0}, \ } #define CONFIG_HLP_NSA "Enable NSA mode \n" @@ -217,6 +219,7 @@ extern int usrp_tx_thread; #define SOFTMODEM_GNB_BIT (1<<21) #define SOFTMODEM_4GUE_BIT (1<<22) #define SOFTMODEM_5GUE_BIT (1<<23) +#define SOFTMODEM_NOSTATS_BIT (1<<24) #define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT) #define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}} @@ -234,6 +237,7 @@ extern int usrp_tx_thread; #define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT) #define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT) #define IS_SOFTMODEM_5GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_5GUE_BIT) +#define IS_SOFTMODEM_NOSTATS_BIT ( get_softmodem_optmask() & SOFTMODEM_NOSTATS_BIT) typedef struct { uint64_t optmask; diff --git a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt deleted file mode 100644 index 2983268dac..0000000000 --- a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt +++ /dev/null @@ -1,64 +0,0 @@ -SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX --2.000000 1.000000 0.346185 0.258473 44.551218 31.688925 357.883903 217.655668 12.810778 326.852166 5.000000 0.000000 5 --1.900000 1.000000 0.345395 0.256275 40.787109 4.190954 65.926488 215.687102 4.300128 230.585721 5.000000 0.000000 5 --1.800000 1.000000 0.343100 0.253634 40.748628 3.912915 56.669470 215.314020 4.139156 227.806468 5.000000 0.000000 5 --1.700000 1.000000 0.341806 0.250634 40.550845 3.347808 56.032851 216.839001 5.959734 244.483352 5.000000 0.000000 5 --1.600000 1.000000 0.339245 0.248129 40.457158 3.735092 56.853508 215.747244 4.995522 242.867659 5.000000 0.000000 5 --1.500000 1.000000 0.337230 0.245763 41.178595 4.297429 56.265874 215.785600 4.151781 227.795995 5.000000 0.000000 5 --1.400000 1.000000 0.335131 0.243311 39.915221 2.739586 55.454917 216.866764 6.547848 251.528327 5.000000 0.000000 5 --1.300000 1.000000 0.333085 0.240664 40.119215 3.044973 55.978253 216.208443 4.459816 228.810686 5.000000 0.000000 5 --1.200000 1.000000 0.330664 0.238769 40.507713 2.998241 55.701876 215.868796 3.778455 226.049304 5.000000 0.000000 5 --1.100000 1.000000 0.329130 0.235812 41.038895 4.522472 56.760814 215.654663 4.746822 236.021980 5.000000 0.000000 5 --1.000000 1.000000 0.325980 0.233534 41.067622 4.626711 57.444142 215.260535 3.481966 225.512853 5.000000 0.000000 5 --0.900000 1.000000 0.323823 0.230863 40.683316 3.689159 56.208182 215.560917 5.180017 243.603452 5.000000 0.000000 5 --0.800000 1.000000 0.321004 0.228222 41.643513 4.717568 58.502452 215.630891 4.283475 238.574145 5.000000 0.000000 5 --0.700000 1.000000 0.317983 0.225520 41.214547 3.941824 56.054211 215.910346 4.375081 227.444626 5.000000 0.000000 5 --0.600000 1.000000 0.316243 0.222903 40.834442 4.370416 56.765508 215.153296 3.617927 226.280086 5.000000 0.000000 5 --0.500000 1.000000 0.312886 0.220473 40.178174 4.185502 64.657291 219.647151 4.454154 236.473446 5.000000 0.000000 5 --0.400000 1.000000 0.309757 0.217536 40.240385 3.172484 55.751563 217.761119 3.900779 228.757195 5.000000 0.000000 5 --0.300000 1.000000 0.305464 0.215229 40.852271 3.761739 56.158869 217.830497 4.087453 230.237764 5.000000 0.000000 5 --0.200000 1.000000 0.302919 0.212364 40.531166 3.688281 56.426841 217.657657 5.498697 253.516146 5.000000 0.000000 5 --0.100000 1.000000 0.298246 0.209310 41.058364 4.140510 59.959571 217.519279 4.087389 228.768313 5.000000 0.000000 5 -0.000000 1.000000 0.294110 0.207107 40.436486 3.604369 55.788895 217.853044 4.012624 236.118036 5.000000 0.000000 5 -0.100000 1.000000 0.288139 0.204033 40.603738 4.045866 57.560760 217.046816 4.583841 244.429411 5.000000 0.000000 5 -0.200000 1.000000 0.285604 0.201954 40.494607 3.886199 59.431970 217.322824 4.080988 233.317513 5.000000 0.000000 5 -0.300000 1.000000 0.278478 0.198929 40.311327 3.452837 56.124657 217.319394 4.434358 232.534720 5.000000 0.000000 5 -0.400000 1.000000 0.270992 0.196299 40.649243 3.415612 56.204178 218.079445 4.990947 245.055337 5.000000 0.000000 5 -0.500000 1.000000 0.263944 0.193661 40.464299 3.622703 56.602842 218.555364 3.936432 229.481159 5.000000 0.000000 5 -0.600000 1.000000 0.256340 0.191194 40.200314 2.474984 53.432412 216.547260 3.695211 227.198078 5.000000 0.000000 5 -0.700000 1.000000 0.251578 0.188606 40.111945 3.029821 54.900896 216.581752 4.247622 237.358365 5.000000 0.000000 5 -0.800000 1.000000 0.234558 0.184742 39.533282 1.182169 42.753097 215.462335 2.960246 226.716604 5.000000 0.000000 5 -0.900000 1.000000 0.225915 0.182691 39.851294 1.108193 42.180342 216.404194 4.450720 228.482353 5.000000 0.000000 5 -1.000000 1.000000 0.216180 0.179994 40.721936 3.302539 56.032206 217.082196 4.599188 227.979232 5.000000 0.000000 5 -1.100000 1.000000 0.203481 0.177332 41.006217 3.798207 56.014901 216.204345 4.292145 227.297386 5.000000 0.000000 5 -1.200000 1.000000 0.188297 0.174121 40.739289 3.269948 56.653507 216.585873 6.250858 251.207034 5.000000 0.000000 5 -1.300000 1.000000 0.172624 0.171622 41.215540 4.783342 55.692883 215.885639 3.629370 226.473280 5.000000 0.000000 5 -1.400000 1.000000 0.156483 0.169110 40.289903 3.749338 56.290861 215.663761 4.176366 225.824735 5.000000 0.000000 5 -1.500000 1.000000 0.136293 0.165692 42.208932 6.070189 69.182665 216.390504 4.816283 235.417446 5.000000 0.000000 5 -1.600000 1.000000 0.125127 0.163325 40.890581 3.941185 56.491504 215.752348 4.426511 226.425984 5.000000 0.000000 5 -1.700000 1.000000 0.104593 0.159971 41.263557 4.128935 57.062514 217.284932 5.311288 249.647163 5.000000 0.000000 5 -1.800000 1.000000 0.091397 0.157460 40.273078 3.062810 55.546913 217.252505 6.331426 251.175692 5.000000 0.000000 5 -1.900000 1.000000 0.078256 0.154628 40.407489 3.419342 56.316166 216.967648 4.712664 245.093313 5.000000 0.000000 5 -2.000000 1.000000 0.065221 0.152571 40.660365 4.317854 57.537407 216.198346 4.991856 245.173269 5.000000 0.000000 5 -2.100000 1.000000 0.053694 0.148885 40.355654 4.062614 60.051963 215.797667 4.447252 236.221454 5.000000 0.000000 5 -2.200000 1.000000 0.042182 0.146229 40.613562 4.124655 56.201536 216.117304 4.060825 227.115987 5.000000 0.000000 5 -2.300000 1.000000 0.034334 0.143612 40.465884 3.541452 55.067611 215.575953 4.891719 244.546802 5.000000 0.000000 5 -2.400000 1.000000 0.026641 0.140869 41.074690 4.697458 61.619188 216.069185 4.700827 233.830937 5.000000 0.000000 5 -2.500000 1.000000 0.019976 0.138112 40.766971 4.274128 58.871741 215.761570 5.633731 249.753931 5.000000 0.000000 5 -2.600000 1.000000 0.012826 0.135122 40.559343 2.952804 54.017706 215.835161 4.039993 226.822103 5.000000 0.000000 5 -2.700000 1.000000 0.010550 0.132915 40.985193 3.330639 55.013950 215.975836 4.240744 227.040703 5.000000 0.000000 5 -2.800000 1.000000 0.007327 0.130133 39.778804 3.002485 56.610555 216.462786 7.082268 265.051418 5.000000 0.000000 5 -2.900000 1.000000 0.004038 0.126763 40.327795 3.934211 55.515352 215.982666 4.626198 230.696124 5.000000 0.000000 5 -3.000000 1.000000 0.003087 0.124336 40.337807 3.537021 55.101627 215.468662 4.177203 230.789145 5.000000 0.000000 5 -3.100000 1.000000 0.001576 0.121689 39.812195 3.116738 55.422687 215.797778 4.091192 225.897780 5.000000 0.000000 5 -3.200000 0.980000 0.001000 0.118928 39.853764 2.871322 56.405555 215.562722 4.187466 232.598421 5.000000 0.000000 5 -3.300000 0.960000 0.000623 0.116065 40.440328 3.580650 56.738889 216.165848 4.735158 240.329999 5.000000 0.000000 5 -3.400000 0.850000 0.000303 0.113505 40.974107 4.291544 56.280236 215.889562 4.448049 237.556780 5.000000 0.000000 5 -3.500000 0.690000 0.000152 0.111010 41.508631 4.251791 56.198873 216.740295 4.889693 242.922934 5.000000 0.000000 5 -3.600000 0.530000 0.000102 0.108493 40.065231 3.643794 57.120823 216.887338 5.242621 250.003843 5.000000 0.000000 5 -3.700000 0.320000 0.000043 0.105612 40.462159 4.162383 56.782173 216.465615 3.846314 227.022697 5.000000 0.000000 5 -3.800000 0.210000 0.000032 0.103084 42.192455 6.207380 64.648964 217.030913 4.482820 228.095918 5.000000 0.000000 5 -3.900000 0.110000 0.000013 0.100391 40.640286 3.715782 55.922914 217.726055 4.553212 236.362804 5.000000 0.000000 5 -4.000000 0.050000 0.000006 0.097518 40.437760 2.838308 54.764308 218.230040 4.309275 237.932625 5.000000 0.000000 5 -4.100000 0.020000 0.000002 0.095436 41.347934 4.608500 64.182062 217.408836 4.385757 228.219627 5.000000 0.000000 5 -4.200000 0.000000 0.000000 0.092396 40.782371 3.621708 55.984245 217.579878 4.102149 228.145363 5.000000 0.000000 5 diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index d13dc5d1c5..8cc1bda782 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -217,7 +217,7 @@ void oai_create_enb(void) { } // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY - // that will result in eNB->configured being set to TRUE. + // that will result in eNB->configured being set to true. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); @@ -267,7 +267,7 @@ void oai_create_gnb(void) { // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY - // that will result in gNB->configured being set to TRUE. + // that will result in gNB->configured being set to true. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n"); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index ba66daa9c0..6d40752a9a 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -20,6 +20,7 @@ #define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03 #define FAPI_NR_DCI_IND 0x04 #define FAPI_NR_RX_PDU_TYPE_RAR 0x05 +#define FAPI_NR_CSIRS_IND 0x06 #define FAPI_NR_SIBS_MASK_SIB1 0x1 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index fd9af01720..a28762d1ff 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -36,9 +36,6 @@ */ - - - typedef struct { uint8_t uci_format; uint8_t uci_channel; @@ -50,7 +47,14 @@ typedef struct { uint32_t sr; } fapi_nr_uci_pdu_rel15_t; - +typedef struct { + uint32_t rsrp; + int rsrp_dBm; + uint8_t rank_indicator; + uint8_t i1; + uint8_t i2; + uint8_t cqi; +} fapi_nr_csirs_measurements_t; typedef struct { /// frequency_domain_resource; @@ -87,7 +91,7 @@ typedef struct { // N_CCE is L, or number of CCEs for DCI int N_CCE; uint8_t payloadSize; - uint8_t payloadBits[16]; + uint8_t payloadBits[16] __attribute__((aligned(16))); // will be cast as uint64 //fapi_nr_dci_pdu_rel15_t dci; } fapi_nr_dci_indication_pdu_t; @@ -130,6 +134,7 @@ typedef struct { fapi_nr_pdsch_pdu_t pdsch_pdu; fapi_nr_ssb_pdu_t ssb_pdu; fapi_nr_sib_pdu_t sib_pdu; + fapi_nr_csirs_measurements_t csirs_measurements; }; } fapi_nr_rx_indication_body_t; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 8b564a5e37..3a7dd8d523 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -738,7 +738,7 @@ typedef struct { // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8 uint16_t PayloadSizeBits; // DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB - uint8_t Payload[DCI_PAYLOAD_BYTE_LEN]; + uint8_t Payload[DCI_PAYLOAD_BYTE_LEN] __attribute__((aligned(32))); } nfapi_nr_dl_dci_pdu_t; @@ -1666,41 +1666,34 @@ typedef struct } nfapi_nr_uci_indication_t; -//3.4.10 srs_indication -//table 3-73 -typedef struct -{ - uint8_t rb_snr; -}nfapi_nr_srs_indication_reported_symbol_resource_block_t; +/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10, Table 3-73 -typedef struct -{ - uint16_t num_rbs; +typedef struct { + uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid. +} nfapi_nr_srs_indication_reported_symbol_resource_block_t; + +typedef struct { + uint16_t num_rbs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272. nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; -}nfapi_nr_srs_indication_reported_symbol_t; +} nfapi_nr_srs_indication_reported_symbol_t; -#define NFAPI_NR_SRS_IND_MAX_PDU 100 -typedef struct -{ - uint32_t handle; - uint16_t rnti; - uint16_t timing_advance; - uint8_t num_symbols; - uint8_t wide_band_snr; - uint8_t num_reported_symbols; +typedef struct { + uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU. + uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535. + uint16_t timing_advance; // Timing advance TA measured for the UE [TS 38.213, Section 4.2]. NTA_new = NTA_old + (TA − 31) * 16 * 64 / (2^u). Value: 0 -> 63. 0xffff should be set if this field is invalid. + uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1. + uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid. + uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4. nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; +} nfapi_nr_srs_indication_pdu_t; -}nfapi_nr_srs_indication_pdu_t; - -typedef struct -{ +typedef struct { nfapi_p7_message_header_t header; - uint16_t sfn; - uint16_t slot; - uint8_t number_of_pdus; + uint16_t sfn; // SFN. Value: 0 -> 1023 + uint16_t slot; // Slot. Value: 0 -> 159 + uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255 nfapi_nr_srs_indication_pdu_t* pdu_list; - } nfapi_nr_srs_indication_t; diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index 264b25deca..af02a16054 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -814,7 +814,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, llr_t *s1,*s2,*yp1,*yp2,*yp; unsigned int i,j,iind;//,pi; unsigned char iteration_cnt=0; - unsigned int crc,oldcrc,crc_len; + unsigned int crc, crc_len; uint8_t temp; #if defined(__x86_64__) || defined(__i386__) __m128i *yp128; @@ -1233,8 +1233,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, } // check the CRC - oldcrc= *((unsigned int *)(&decoded_bytes[(n>>3)-crc_len])); - + uint32_t oldcrc; + memcpy(&oldcrc, &decoded_bytes[(n >> 3) - crc_len], crc_len); switch (crc_type) { case CRC24_A: oldcrc&=0x00ffffff; diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 9ad18cc1a6..471b26fe24 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -244,11 +244,11 @@ crc16 (unsigned char * inptr, int bitlen) while (octetlen-- > 0) { - crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16); + crc = (crc << 8) ^ (((uint32_t)crc16Table[(*inptr++) ^ (crc >> 24)]) << 16); } if (resbit > 0) - crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16); + crc = (crc << resbit) ^ (((uint32_t)crc16Table[(*inptr) >> (8 - resbit) ^ (crc >> (32 - resbit))]) << 16); return crc; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h index f4ea4a9434..f792f993e9 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h @@ -961,7 +961,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1028,7 +1029,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1096,7 +1098,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1163,7 +1166,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1230,7 +1234,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1297,7 +1302,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1364,7 +1370,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1431,7 +1438,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1498,7 +1506,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1593,7 +1602,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1660,7 +1670,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1727,7 +1738,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1794,7 +1806,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1861,7 +1874,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1928,7 +1942,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 76adf4d314..4438bfca95 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -600,38 +600,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, // CSI RS init // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; - gNB->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t)); - gNB->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n"); + gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); + gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); for (int slot=0; slotslots_per_frame; slot++) { - gNB->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); + gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); for (int symb=0; symbsymbols_per_slot; symb++) { - gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); + gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); } } - gNB->nr_csi_rs_info->csi_gold_init = cfg->cell_config.phy_cell_id.value; - nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_rs_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value); + gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value; + nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value); for (int id=0; idnr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - gNB->nr_srs_info[id]->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); - gNB->nr_srs_info[id]->srs_generated_signal = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - gNB->nr_srs_info[id]->srs_received_signal = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_ls_estimated_channel = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_freq = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - for (i=0;inr_srs_info[id]->srs_received_signal[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_ls_estimated_channel[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_freq[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - } } generate_ul_reference_signal_sequences(SHRT_MAX); @@ -779,31 +764,16 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) } free_and_zero(pusch_dmrs); - uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs; + uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs; for (int slot = 0; slot < fp->slots_per_frame; slot++) { for (int symb = 0; symb < fp->symbols_per_slot; symb++) free_and_zero(nr_gold_csi_rs[slot][symb]); free_and_zero(nr_gold_csi_rs[slot]); } free_and_zero(nr_gold_csi_rs); - free_and_zero(gNB->nr_csi_rs_info); + free_and_zero(gNB->nr_csi_info); for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) { - for (int i = 0; i < Prx; i++) { - free_and_zero(gNB->nr_srs_info[id]->srs_received_signal[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i]); - } - free_and_zero(gNB->nr_srs_info[id]->sc_list); - free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal); - free_and_zero(gNB->nr_srs_info[id]->noise_power); - free_and_zero(gNB->nr_srs_info[id]->srs_received_signal); - free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted); free_and_zero(gNB->nr_srs_info[id]); } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index c96aeab432..75d78738fc 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -60,7 +60,7 @@ int nr_phy_init_RU(RU_t *ru) { for (i=0; inb_tx; i++) { // Allocate 10 subframes of I/Q TX signal data (time) if not - ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension +fp->samples_per_frame) *sizeof(int32_t)); + ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t)); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i], (ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t),ru->sf_extension); ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension]; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index c6e6ecd463..3c1f8ac531 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -34,19 +34,6 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/MODULATION/nr_modulation.h" -#if 0 -void phy_config_harq_ue(module_id_t Mod_id, - int CC_id, - uint8_t gNB_id, - uint16_t max_harq_tx) { - int num_of_threads,num_of_code_words; - PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - - for (num_of_threads=0; num_of_threadsulsch[num_of_threads][gNB_id][num_of_code_words]->Mlimit = max_harq_tx; -} -#endif extern uint16_t beta_cqi[16]; @@ -159,7 +146,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; NR_UE_SRS **const srs_vars = ue->srs_vars; - int i, j, slot, symb, gNB_id, th_id; + int i, slot, symb, gNB_id, th_id; LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx); @@ -347,52 +334,23 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; - ue->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t)); - ue->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n"); + ue->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); + ue->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); for (int slot=0; slotslots_per_frame; slot++) { - ue->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); + ue->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); for (int symb=0; symbsymbols_per_slot; symb++) { - ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); + ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); } } - ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) ); + ue->nr_csi_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) ); for (i=0; inr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); - } - ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); - ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) ); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) ); - for (i=0; inb_antennas_rx; i++) { - ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); - ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *)); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *)); - for (j=0; jnr_csi_rs_info->csi_rs_ls_estimated_channel[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t)); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t)); - } + ue->nr_csi_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); } ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); - ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); - ue->nr_srs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - ue->nr_srs_info->srs_received_signal = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_ls_estimated_channel = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_freq = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time_shifted = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - for (i=0; inb_antennas_rx; i++) { - ue->nr_srs_info->srs_received_signal[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_ls_estimated_channel[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_freq[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - } - // RACH prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -486,55 +444,26 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->pdsch_vars[th_id][gNB_id]); } } - + for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) { - free_and_zero(ue->pdcch_vars[th_id][gNB_id]); } for (int i=0; inr_csi_rs_info->csi_rs_generated_signal[i]); - } - for (int i = 0; i < fp->nb_antennas_rx; i++) { - free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]); - for (int j=0; jnr_csi_rs_info->csi_rs_ls_estimated_channel[i][j]); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j]); - } - free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]); + free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]); } + free_and_zero(ue->nr_csi_info->csi_rs_generated_signal); for (int slot=0; slotslots_per_frame; slot++) { for (int symb=0; symbsymbols_per_slot; symb++) { - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot][symb]); } - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot]); } - free_and_zero(ue->nr_csi_rs_info->noise_power); - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs); - free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal); - free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal); - free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq); - free_and_zero(ue->nr_csi_rs_info); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs); + free_and_zero(ue->nr_csi_info); - for (int i = 0; i < fp->nb_antennas_rx; i++) { - free_and_zero(ue->nr_srs_info->srs_received_signal[i]); - free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted[i]); - } - free_and_zero(ue->nr_srs_info->sc_list); - free_and_zero(ue->nr_srs_info->srs_generated_signal); - free_and_zero(ue->nr_srs_info->noise_power); - free_and_zero(ue->nr_srs_info->srs_received_signal); - free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted); free_and_zero(ue->nr_srs_info); free_and_zero(ue->csiim_vars[gNB_id]); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index c867292942..9327fe9fe8 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -41,10 +41,10 @@ extern int16_t *ul_ref_sigs_rx[30][2][34]; int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, L1_rxtx_proc_t *proc, - LTE_eNB_ULSCH_t * ulsch, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, + LTE_eNB_ULSCH_t * ulsch, + int32_t **ul_ch_estimates, + int32_t **ul_ch_estimates_time, + int32_t **rxdataF_ext, module_id_t UE_id, unsigned char l, unsigned char Ns) { @@ -88,7 +88,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, } uint16_t N_rb_alloc = ulsch->harq_processes[harq_pid]->nb_rb; - int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16))); + int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(32))); Msc_RS = N_rb_alloc*12; cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + ulsch->harq_processes[harq_pid]->n_DMRS2 + @@ -334,14 +334,14 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = cmin(abs(current_phase2),127); // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); // rotate channel estimates by estimated phase - rotate_cpx_vector((int16_t *) ul_ch1, - &ru1[2*current_phase1], - (int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + rotate_cpx_vector((c16_t *) ul_ch1, + (c16_t *)&ru1[2*current_phase1], + (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], Msc_RS, 15); - rotate_cpx_vector((int16_t *) ul_ch2, - &ru2[2*current_phase2], - (int16_t *) &tmp_estimates[0], + rotate_cpx_vector((c16_t *) ul_ch2, + (c16_t *)&ru2[2*current_phase2], + (c16_t *) tmp_estimates, Msc_RS, 15); // Combine the two rotated estimates @@ -657,14 +657,14 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = cmin(abs(current_phase2),127); // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); // rotate channel estimates by estimated phase - rotate_cpx_vector((int16_t *) ul_ch1, - &ru1[2*current_phase1], - (int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + rotate_cpx_vector((c16_t *) ul_ch1, + (c16_t *) &ru1[2*current_phase1], + (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], Msc_RS, 15); - rotate_cpx_vector((int16_t *) ul_ch2, - &ru2[2*current_phase2], - (int16_t *) &tmp_estimates[0], + rotate_cpx_vector((c16_t *) ul_ch2, + (c16_t *) &ru2[2*current_phase2], + (c16_t *) &tmp_estimates[0], Msc_RS, 15); // Combine the two rotated estimates diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1bbe9eb39a..dc73a56568 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1997,7 +1997,7 @@ int get_narrowband_index(int N_RB_UL,int rb) { void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) { uint8_t harq_pid; //uint8_t UE_id; - boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE; + const bool new_ulsch = find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST) == -1; //AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, // "No existing/free UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti); LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; @@ -2063,7 +2063,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) || (ulsch->harq_processes[harq_pid]->ndi != ulsch_pdu->ulsch_pdu_rel8.new_data_indication) || - (new_ulsch == TRUE)) { + (new_ulsch == true)) { ulsch->harq_processes[harq_pid]->status = ACTIVE; ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c index 64e74ebfbf..0addfdf14c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -532,9 +532,12 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { } +// FIXME: this function is compting PRB outside the range, so I FORCED in the range +// I can't understand the 3GPP spec, see below note uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { int offset; + int ret=-1; switch (N_RB_DL) { @@ -545,16 +548,16 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { switch (vrb) { case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 case 1: - return ((3*odd_slot) + 2*(vrb&3))%6; + ret= ((3*odd_slot) + 2*(vrb&3))%6; break; case 2: // even: 2->3, 3->5, odd: 2->0, 3->2 case 3: - return ((3*odd_slot) + 2*(vrb&3) + 5)%6; + ret= ((3*odd_slot) + 2*(vrb&3) + 5)%6; break; case 4: // even: 4->1, odd: 4->4 - return ((3*odd_slot) + 1)%6; + ret= ((3*odd_slot) + 1)%6; case 5: // even: 5->4, odd: 5->1 - return ((3*odd_slot) + 4)%6; + ret= ((3*odd_slot) + 4)%6; break; } break; @@ -562,88 +565,90 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { case 15: if (vrb<12) { if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 - return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); + ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 - return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); + ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); } if (vrb==12) - return (3+(7*odd_slot)) % 14; + ret= (3+(7*odd_slot)) % 14; if (vrb==13) - return (10+(7*odd_slot)) % 14; - return 14; + ret= (10+(7*odd_slot)) % 14; + ret= 14; break; + // Formula in TS 36.211, chap 6.2.3.2 + // Fix me: returns a PRB number > 24 when vrb is 24 case 25: - return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); + ret= (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); break; case 50: // P=3 if (Ngap==0) { // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 if (vrb>=23) - offset=4; + offset=4; else - offset=0; + offset=0; if (vrb<44) { - if ((vrb&3)>=2) - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; - else - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; + if ((vrb&3)>=2) + ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; + else + ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; } if (vrb==44) // even: 44->11, odd: 45->34 - return offset+((23*odd_slot) + 22-12+1); + ret= offset+((23*odd_slot) + 22-12+1); if (vrb==45) // even: 45->10, odd: 45->33 - return offset+((23*odd_slot) + 22+12); + ret= offset+((23*odd_slot) + 22+12); if (vrb==46) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + ret= offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==47) - return offset+46+((23*odd_slot) + 23+12) % 46; + ret= offset+46+((23*odd_slot) + 23+12) % 46; if (vrb==48) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + ret= offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==49) - return offset+46+((23*odd_slot) + 23+12) % 46; + ret= offset+46+((23*odd_slot) + 23+12) % 46; } else { // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 if (vrb>=9) - offset=18; + offset=18; else - offset=0; + offset=0; if (vrb<12) { - if ((vrb&3)>=2) - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; - else - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; + if ((vrb&3)>=2) + ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; + else + ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; } else { - return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); + ret= offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); } } break; case 75: // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 if (Ngap ==0) { - return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); + ret= ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; case 100: // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 if (Ngap ==0) { - return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); + ret= ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; default: LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL); - return 0; + ret= 0; } - return 0; + return ret%N_RB_DL; } @@ -677,7 +682,7 @@ void generate_RIV_tables(void) // printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs); localRIV2alloc_LUT6[RIV] = alloc0; - distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; + distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd; RIV2nb_rb_LUT6[RIV] = Lcrbs; RIV2first_rb_LUT6[RIV] = RBstart; @@ -693,15 +698,14 @@ void generate_RIV_tables(void) nVRB = Lcrbs-1+RBstart; //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); alloc0 |= (1<RIV_max25) - RIV_max25 = RIV;; - + RIV_max25 = RIV; localRIV2alloc_LUT25[RIV] = alloc0; distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even; @@ -730,37 +734,37 @@ void generate_RIV_tables(void) if (nVRB<32) - alloc0 |= (1< nVRB_even_dist %d\n",nVRB,nVRB_even_dist); - if (nVRB_even_dist<32) - allocdist0_0_even |= (1<(%08x.%08x.%08x.%08x)\n", allocdist0_0_even, @@ -845,38 +848,37 @@ void generate_RIV_tables(void) // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,0); if (nVRB_odd_dist<32) - allocdist0_0_odd |= (1<dlsch->harq_processes[harq_pid]; if ( rdata-> round == 0) { - uint8_t tmp[96+12+3+3*6144]; + uint8_t tmp[96+12+3+3*6144] __attribute__((aligned(32))); memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS); start_meas(rdata->te_stats); encoder(rdata->input, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index 088e2c0a5e..b5e5b490a3 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -64,6 +64,12 @@ extern uint16_t beta_cqi[16]; extern uint16_t beta_ri[16]; extern uint16_t beta_ack[16]; +static int errorRB(int rb, char * table, int line) { + LOG_E(PHY,"Received %d rb, impossble in table %s, at line %d\n", rb, table, line); + return 0; +} + +#define rbAllocCheck(RBalL, TabLe) (RBalL) > sizeof(TabLe)/sizeof(*TabLe) ? errorRB(RBalL, #TabLe, __LINE__) : TabLe[RBalL] void extract_dci1A_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint8_t harq_pid=0; @@ -974,28 +980,28 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, { switch (N_RB_DL) { case 6: - NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc, RIV2nb_rb_LUT6); if(rah) RIV_max = RIV_max6; else RIV_max = 0x3F; break; case 25: - NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT25); if(rah) RIV_max = RIV_max25; else RIV_max = 0x1FFF; break; case 50: - NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT50); if(rah) RIV_max = RIV_max50; else RIV_max = 0x1FFFF; break; case 100: - NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT100); if(rah) RIV_max = RIV_max100; else @@ -1034,9 +1040,14 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, // this is an eNB issue // retransmisison but old and new TBS are different !!! // work around, consider it as a new transmission - LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); + LOG_E(PHY, + "Format1A Retransmission but TBS are different: consider it as new transmission !!!, round %d, mcs 1 %d, NPRB %d \n", + pdlsch0_harq->round, + mcs1, + NPRB); pdlsch0_harq->round = 0; //return(0); // ?? to cross check + return(0); // ?? to cross check } } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 0b665737a7..8f5e33d6e0 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -41,7 +41,7 @@ #include #include #include -#if RHEL_RELEASE_CODE >= 1796 +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403 #include #include #else diff --git a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c index 7d063e326e..83c74389cf 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c @@ -14,7 +14,7 @@ data storage. */ #include #include #include -#if RHEL_RELEASE_CODE >= 1796 +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403 #include #include #else diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index f5b8c6b64a..36da4ccab0 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -1272,14 +1272,6 @@ uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb); @return Transport block size */ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb); -/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type - @param N_RB_DL number of PRB on DL - @param indicator for even/odd slot - @param vrb vrb index - @param Ngap Gap indicator -*/ -uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap); - /* \brief Return prb for a given vrb index @param vrb_type VRB type (0=localized,1=distributed) @param rb_alloc_dci rballoc field from DCI diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h index b4ae44f6ea..5f8763414e 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h @@ -90,7 +90,7 @@ typedef struct { /// Redundancy-version of the current sub-frame uint8_t rvidx; /// Turbo-code outputs (36-212 V8.6 2009-03, p.12 - uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))]; + uint8_t *d[MAX_NUM_ULSCH_SEGMENTS]; /// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17) uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144]; /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c index ae3ebbce9d..c04ec160aa 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c @@ -71,6 +71,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) { for (r=0; rharq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); + free16(ulsch->harq_processes[i]->d[r],0); ulsch->harq_processes[i]->c[r] = NULL; } } @@ -86,7 +87,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) { LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { LTE_UE_ULSCH_t *ulsch; - unsigned char exit_flag = 0,i,j,r; + unsigned char exit_flag = 0; unsigned char bw_scaling =1; switch (N_RB_UL) { @@ -113,7 +114,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { memset(ulsch,0,sizeof(LTE_UE_ULSCH_t)); ulsch->Mlimit = 4; - for (i=0; i<8; i++) { + for (int i=0; i<8; i++) { ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t)); // printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]); @@ -129,15 +130,11 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { } if (abstraction_flag==0) { - for (r=0; rharq_processes[i]->c[r] = (unsigned char *)malloc16(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case - - if (ulsch->harq_processes[i]->c[r]) - memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768); - else { - LOG_E(PHY,"Can't get c\n"); - exit_flag=2; - } + for (int r=0; rharq_processes[i]->c[r] = malloc16_clear(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case + AssertFatal(ulsch->harq_processes[i]->c[r], ""); + ulsch->harq_processes[i]->d[r] = malloc16_clear(96+3+(3*6144)); + AssertFatal(ulsch->harq_processes[i]->d[r], ""); } } @@ -148,15 +145,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { exit_flag=3; } } - - if ((abstraction_flag == 0) && (exit_flag==0)) { - for (i=0; i<8; i++) - for (j=0; j<96; j++) - for (r=0; rharq_processes[i]->d[r][j] = LTE_NULL; - - return(ulsch); - } else if (abstraction_flag==1) + if (!exit_flag) return(ulsch); } @@ -191,7 +180,7 @@ uint32_t ulsch_encoding(uint8_t *a, uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0; // uint32_t E; uint8_t ack_parity; - uint32_t i,q,j,iprime,j2; + uint32_t q,j,iprime,j2; uint16_t o_RCC; uint8_t o_flip[8]; uint32_t wACK_idx; @@ -327,6 +316,8 @@ uint32_t ulsch_encoding(uint8_t *a, #endif // offset=0; start_meas(te_stats); + for (int z=0; z<96; z++) + ulsch->harq_processes[harq_pid]->d[r][z] = LTE_NULL; encoder(ulsch->harq_processes[harq_pid]->c[r], Kr>>3, &ulsch->harq_processes[harq_pid]->d[r][96], @@ -539,8 +530,6 @@ uint32_t ulsch_encoding(uint8_t *a, ulsch->q); } - i=0; - // Do RI coding if (ulsch->O_RI == 1) { switch (Q_m) { @@ -691,7 +680,7 @@ uint32_t ulsch_encoding(uint8_t *a, j=0; - for (i=0; i>2); for (q=0; q>2); for (q=0; qh[j++] = *yptr++; @@ -818,7 +807,7 @@ uint32_t ulsch_encoding(uint8_t *a, break; case 4: - for (i=0; ih[j++] = *yptr++; @@ -830,7 +819,7 @@ uint32_t ulsch_encoding(uint8_t *a, break; case 6: - for (i=0; ih[j++] = *yptr++; diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 8352a7f5a6..979a31c504 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -226,10 +226,11 @@ void nr_modulation(uint32_t *in, i *= 24; bit_cnt = i * 8; while (bit_cnt < length) { - x = *((uint32_t*)(in_bytes+i)); - x1 = x&4095; + uint32_t xx; + memcpy(&xx, in_bytes+i, sizeof(xx)); + x1 = xx & 4095; out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>12)&4095; + x1 = (xx >> 12) & 4095; out64[j++] = nr_64qam_mod_table[x1]; i += 3; bit_cnt += 24; @@ -617,47 +618,38 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { for (uint8_t ll = 0; ll < 2; ll++){ double f0 = f[ll]; - double Ncpm1 = Ncp0; - int16_t *symbol_rotation = fp->symbol_rotation[ll]; - - double tl = 0; - double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; - double exp_re = cos(poff); - double exp_im = sin(-poff); - symbol_rotation[0] = (int16_t)floor(exp_re * 32767); - symbol_rotation[1] = (int16_t)floor(exp_im * 32767); LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); - LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n", - 0, - nsymb, - symbol_rotation[0], - symbol_rotation[1]); + c16_t *symbol_rotation = fp->symbol_rotation[ll]; - for (int l = 1; l < nsymb; l++) { + double tl = 0.0; + double poff = 0.0; + double exp_re = 0.0; + double exp_im = 0.0; + + for (int l = 0; l < nsymb; l++) { double Ncp; - if (l == (7 * (1 << fp->numerology_index))) { + if (l == 0 || l == (7 * (1 << fp->numerology_index))) { Ncp = Ncp0; } else { Ncp = Ncp1; } - tl += (Nu + Ncpm1) * Tc; poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0; exp_re = cos(poff); exp_im = sin(-poff); - symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767); - symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767); + symbol_rotation[l].r = (int16_t)floor(exp_re * 32767); + symbol_rotation[l].i = (int16_t)floor(exp_im * 32767); LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", l, nsymb, tl, - symbol_rotation[l<<1], - symbol_rotation[1 + (l<<1)], + symbol_rotation[l].r, + symbol_rotation[l].i, (poff / 2 / M_PI) - floor(poff / 2 / M_PI)); - Ncpm1 = Ncp; + tl += (Nu + Ncp) * Tc; } } @@ -670,13 +662,13 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) double poff = -i * 2.0 * M_PI * sample_offset / fp->ofdm_symbol_size; double exp_re = cos(poff); double exp_im = sin(-poff); - fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767); - fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767); + fp->timeshift_symbol_rotation[i].r = (int16_t)round(exp_re * 32767); + fp->timeshift_symbol_rotation[i].i = (int16_t)round(exp_im * 32767); if (i < 10) LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i, - fp->timeshift_symbol_rotation[i*2], - fp->timeshift_symbol_rotation[i*2+1], + fp->timeshift_symbol_rotation[i].r, + fp->timeshift_symbol_rotation[i].i, poff); } } diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 2f075e8218..0b8f22a094 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -46,18 +46,18 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA PHY_ofdm_mod(txdataF, // input - txdata, // output - frame_parms->ofdm_symbol_size, + txdata, // output + frame_parms->ofdm_symbol_size, - 1, // number of symbols - frame_parms->nb_prefix_samples0, // number of prefix samples - CYCLIC_PREFIX); + 1, // number of symbols + frame_parms->nb_prefix_samples0, // number of prefix samples + CYCLIC_PREFIX); PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input - txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output - frame_parms->ofdm_symbol_size, - nsymb-1, - frame_parms->nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); + txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output + frame_parms->ofdm_symbol_size, + nsymb-1, + frame_parms->nb_prefix_samples, // number of prefix samples + CYCLIC_PREFIX); @@ -341,14 +341,14 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne } void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, - int16_t* trxdata, - int slot, - int first_symbol, - int nsymb, - int length) { + int16_t* trxdata, + int slot, + int first_symbol, + int nsymb, + int length) { int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot; - int16_t *symbol_rotation = fp->symbol_rotation[0]; + c16_t *symbol_rotation = fp->symbol_rotation[0]; for (int sidx=0;sidxrx_dft_stats); int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + c16_t rot2 = frame_parms->symbol_rotation[0][symbol+symb_offset]; + rot2.i=-rot2.i; #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, - symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + symbol+symb_offset,rot2.r,rot2.i); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + &rot2, + (c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); - int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - shift_rot, + (int16_t *)shift_rot, (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1, frame_parms->ofdm_symbol_size, @@ -214,18 +214,18 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, stop_meas(&ue->rx_dft_stats); int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + c16_t rot2 = frame_parms->symbol_rotation[0][symbol + symb_offset]; + rot2.i=-rot2.i; #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, - symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + symbol+symb_offset,rot2.r,rot2.i); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + &rot2, + (c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); } @@ -310,19 +310,19 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, for (int symbol=first_symbol;symbolsymbol_rotation[1])[symbol + symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); - rotate_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], - (int16_t*)&rot2, - (int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], + c16_t rot2 = frame_parms->symbol_rotation[1][symbol + symb_offset]; + rot2.i=-rot2.i; + LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i); + rotate_cpx_vector((c16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], + &rot2, + (c16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], length, 15); - int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; multadd_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], - shift_rot, + (int16_t *)shift_rot, (int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], 1, length, diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index fb56322e54..c527c3fc9d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -67,6 +67,49 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) return max_pos - sync_pos; } +int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, + const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) { + int timing_advance = 0; + int max_val = 0; + + for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { + int temp = 0; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r; + int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i; + temp += (Re*Re/2) + (Im*Im/2); + } + if (temp > max_val) { + timing_advance = i; + max_val = temp; + } + } + + if (timing_advance > frame_parms->ofdm_symbol_size/2) { + timing_advance = timing_advance - frame_parms->ofdm_symbol_size; + } + + // Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7; + + // do some integer rounding to improve TA accuracy + int sync_pos_rounded; + if (timing_advance > 0) { + sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1; + } else { + sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1; + } + + int timing_advance_update = sync_pos_rounded / bw_scaling; + + // put timing advance command in 0..63 range + timing_advance_update += 31; + + if (timing_advance_update < 0) timing_advance_update = 0; + if (timing_advance_update > 63) timing_advance_update = 63; + + return timing_advance_update; +} void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { @@ -108,9 +151,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; int rb, nb_symb[275]={0}; - + memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power)); - + for (int s=first_symb;s<(first_symb+num_symb);s++) { for (rb=0; rbN_RB_UL; rb++) { if (s==first_symb /*&& ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0)*/) { @@ -119,13 +162,13 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb measurements->n0_subband_power[aarx][rb]=0; } int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; - if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe + if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0) { // check that rb was not used in this subframe nb_symb[rb]++; for (int aarx=0; aarxnb_antennas_rx; aarx++) { int offset = offset0 + (s*frame_parms->ofdm_symbol_size); int32_t *ul_ch = &common_vars->rxdataF[aarx][offset]; int len = 12; - if (((frame_parms->N_RB_UL&1) == 1) && + if (((frame_parms->N_RB_UL&1) == 1) && (rb==(frame_parms->N_RB_UL>>1))) { len=6; } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index cd3b535b3f..e5c1ca37d8 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -854,7 +854,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint32_t nb_re_pusch) { //#define DEBUG_UL_PTRS 1 - int16_t *phase_per_symbol = NULL; int32_t *ptrs_re_symbol = NULL; int8_t ret = 0; @@ -871,20 +870,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset; /* loop over antennas */ for (int aarx=0; aarxnb_antennas_rx; aarx++) { - phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx]; + c16_t *phase_per_symbol = (c16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx]; ptrs_re_symbol = &gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot; *ptrs_re_symbol = 0; - phase_per_symbol[(2*symbol)+1] = 0; // Imag + phase_per_symbol[symbol].i = 0; /* set DMRS estimates to 0 angle with magnitude 1 */ if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { /* set DMRS real estimation to 32767 */ - phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 + phase_per_symbol[symbol].r=INT16_MAX; // 32767 #ifdef DEBUG_UL_PTRS - printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i); #endif } else {// real ptrs value is set to 0 - phase_per_symbol[2*symbol] = 0; // Real + phase_per_symbol[symbol].r = 0; } if(symbol == *startSymbIndex) { @@ -909,7 +908,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)], gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol], - &phase_per_symbol[2* symbol], + (int16_t*)&phase_per_symbol[symbol], ptrs_re_symbol); } /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/ @@ -919,7 +918,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /*------------------------------------------------------------------------------------------------------- */ /* If L-PTRS is > 0 then we need interpolation */ if(*L_ptrs > 0) { - ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb); if(ret != 0) { LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } @@ -938,11 +937,11 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /* Skip rotation if the slot processing is wrong */ if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_UL_PTRS - printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); + printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], - &phase_per_symbol[2* i], - (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + &phase_per_symbol[i], + (c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop @@ -950,9 +949,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, }//Antenna loop } -uint32_t calc_power(uint16_t *x, uint32_t size) { - uint64_t sum_x = 0; - uint64_t sum_x2 = 0; +uint32_t calc_power(const int16_t *x, const uint32_t size) { + int64_t sum_x = 0; + int64_t sum_x2 = 0; for(int k = 0; kframe_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power_per_rb, + uint32_t *noise_power, + int8_t *snr_per_rb, + int8_t *snr) { if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); return -1; } - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - int32_t **srs_ls_estimated_channel = nr_srs_info->srs_ls_estimated_channel; + const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - uint16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - uint16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; int16_t ls_estimated[2]; @@ -994,11 +999,11 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - int16_t generated_real = srs_generated_signal[nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t generated_imag = (srs_generated_signal[nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + int16_t generated_real = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].r; + int16_t generated_imag = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].i; - int16_t received_real = srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t received_imag = (srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + int16_t received_real = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].r; + int16_t received_imag = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].i; // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. @@ -1069,8 +1074,10 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, // Compute noise for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) & 0xFFFF)); - noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)(((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) >> 16) & 0xFFFF)); + ch_real[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].r; + ch_imag[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].i; + noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].r - ch_real[ant*nr_srs_info->sc_list_length + sc_idx]); + noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].i - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx]); } // Convert to time domain @@ -1087,11 +1094,74 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); } + // Compute signal power + *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); +#endif + + if (*signal_power == 0) { + LOG_W(NR_PHY, "Received SRS signal power is 0\n"); + return -1; + } + + // Compute noise power + + const uint8_t signal_power_bits = log2_approx(*signal_power); + const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x) + const int32_t factor_dB = dB_fixed(1<first_carrier_offset + srs_pdu->bwp_start*12; + const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3; + const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb; + uint8_t count_estimates = 0; + uint64_t sum_re = 0; + uint64_t sum_re2 = 0; + uint64_t sum_im = 0; + uint64_t sum_im2 = 0; + + for (int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { + + int subcarrier0 = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; + if(subcarrier0 < 0) { + subcarrier0 = subcarrier0 + frame_parms->ofdm_symbol_size; + } + int rb = subcarrier0/NR_NB_SC_PER_RB; + + for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + + sum_re = sum_re + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_re2 = sum_re2 + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]*noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_im = sum_im + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; + + count_estimates++; + if (count_estimates == n_noise_est) { + noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + + sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1); + snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<nb_antennas_rx*nr_srs_info->sc_list_length) + calc_power(noise_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + *snr = dB_fixed((int32_t)((*signal_power<first_carrier_offset + srs_pdu->bwp_start*12; uint8_t R = srs_pdu->comb_size == 0 ? 2 : 4; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { @@ -1119,7 +1189,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, } } - LOG_I(NR_PHY,"noise_power = %u\n", *noise_power); + LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", *noise_power, *snr); #endif return 0; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index a01106adb5..b0ed3662ea 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -55,6 +55,9 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); +int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, + const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); + void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul, @@ -63,15 +66,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, unsigned char symbol, uint32_t nb_re_pusch); -int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_srs_pdu_t *srs_pdu, - nr_srs_info_t *nr_srs_info, - int32_t *srs_generated_signal, - int32_t **srs_received_signal, - int32_t **srs_estimated_channel_freq, - int32_t **srs_estimated_channel_time, - int32_t **srs_estimated_channel_time_shifted, - uint32_t *noise_power); +int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const int32_t *srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], + int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power_per_rb, + uint32_t *noise_power, + int8_t *snr_per_rb, + int8_t *snr); #endif diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index d4d91d7060..110ff321bd 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB); */ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid); -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid); diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index eb5c573368..a6e57fb298 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -68,6 +68,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid); -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index ab8d915d6e..0a1619f3e0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -27,7 +27,7 @@ //#define NR_CSIRS_DEBUG -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { uint32_t x1, x2; uint8_t reset; int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; @@ -43,12 +43,20 @@ void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { } } -void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, +void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, - int16_t amp, - nr_csi_rs_info_t *nr_csi_rs_info, - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, - int slot){ + const int16_t amp, + nr_csi_info_t *nr_csi_info, + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, + const int slot, + uint8_t *N_cdm_groups, + uint8_t *CDM_group_size, + uint8_t *k_prime, + uint8_t *l_prime, + uint8_t *N_ports, + uint8_t *j_cdm, + uint8_t *k_overline, + uint8_t *l_overline) { #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing); @@ -67,11 +75,11 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss); #endif - int dataF_offset = slot*frame_parms.samples_per_slot_wCP; - uint32_t **nr_gold_csi_rs = nr_csi_rs_info->nr_gold_csi_rs[slot]; + int dataF_offset = slot*frame_parms->samples_per_slot_wCP; + uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot]; //*8(max allocation per RB)*2(QPSK)) - int csi_rs_length = frame_parms.N_RB_DL<<4; - int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); + int csi_rs_length = frame_parms->N_RB_DL<<4; + int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); uint16_t b = csi_params->freq_domain; uint16_t n, p, k, l, mprime, na, kpn; uint8_t size, ports, kprime, lprime, i, gs; @@ -81,14 +89,14 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, uint8_t fi = 0; double rho, alpha; uint32_t beta = amp; - nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp); + nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp); AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs - if (csi_params->scramb_id != nr_csi_rs_info->csi_gold_init) { - nr_csi_rs_info->csi_gold_init = csi_params->scramb_id; - nr_init_csi_rs(&frame_parms, nr_csi_rs_info->nr_gold_csi_rs, csi_params->scramb_id); + if (csi_params->scramb_id != nr_csi_info->csi_gold_init) { + nr_csi_info->csi_gold_init = csi_params->scramb_id; + nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id); } switch (csi_params->row) { @@ -584,7 +592,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, } } - uint16_t start_sc = frame_parms.first_carrier_offset; + uint16_t start_sc = frame_parms->first_carrier_offset; // resource mapping according to 38.211 7.4.1.5.3 for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) { @@ -593,7 +601,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, for (int s=0 ; sofdm_symbol_size); // frequency index of current resource element // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 if (kp == 0) wf = 1; @@ -620,17 +628,17 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, // ZP CSI RS if (csi_params->csi_type == 2) { - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0; - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0; } else { - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15; - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; } #ifdef NR_CSIRS_DEBUG printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000, - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)], - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)], + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); #endif } } @@ -638,23 +646,25 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, } } } - nr_csi_rs_info->N_cdm_groups = size; - nr_csi_rs_info->CDM_group_size = gs; - nr_csi_rs_info->kprime = kprime; - nr_csi_rs_info->lprime = lprime; - nr_csi_rs_info->N_ports = ports; - memcpy(nr_csi_rs_info->j,j,16*sizeof(uint8_t)); - memcpy(nr_csi_rs_info->koverline,koverline,16*sizeof(uint8_t)); - memcpy(nr_csi_rs_info->loverline,loverline,16*sizeof(uint8_t)); + if (N_cdm_groups) *N_cdm_groups = size; + if (CDM_group_size) *CDM_group_size = gs; + if (k_prime) *k_prime = kprime; + if (l_prime) *l_prime = lprime; + if (N_ports) *N_ports = ports; + if (j_cdm) memcpy(j_cdm,j,16*sizeof(uint8_t)); + if (k_overline) memcpy(k_overline,koverline,16*sizeof(uint8_t)); + if (l_overline) memcpy(l_overline,loverline,16*sizeof(uint8_t)); #ifdef NR_CSIRS_DEBUG - LOG_I(NR_PHY, "nr_csi_rs_info->N_ports = %d\n", nr_csi_rs_info->N_ports); - LOG_I(NR_PHY, "nr_csi_rs_info->N_cdm_groups = %d\n", nr_csi_rs_info->N_cdm_groups); - LOG_I(NR_PHY, "nr_csi_rs_info->CDM_group_size = %d\n", nr_csi_rs_info->CDM_group_size); - LOG_I(NR_PHY, "nr_csi_rs_info->kprime = %d\n", nr_csi_rs_info->kprime); - LOG_I(NR_PHY, "nr_csi_rs_info->lprime = %d\n", nr_csi_rs_info->lprime); - for(int ji=0; jiN_cdm_groups; ji++) { - LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, nr_csi_rs_info->j[ji], nr_csi_rs_info->koverline[ji], nr_csi_rs_info->loverline[ji]); + if (N_ports) LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports); + if (N_cdm_groups) LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups); + if (CDM_group_size) LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size); + if (k_prime) LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime); + if (l_prime) LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime); + if (N_cdm_groups) { + for(int ji=0; ji<*N_cdm_groups; ji++) { + LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]); + } } #endif } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index d70d991e7b..dc1ed47e0f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -111,9 +111,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // DMRS length is per OFDM symbol uint32_t dmrs_length = n_rb*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) - 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", - rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType, - dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits); + 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", + rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType, + dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits); dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset /// DMRS QPSK modulation @@ -122,11 +123,11 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_PDCCH_DMRS - if(dci_pdu->RNTI!=0xFFFF) { - for (int i=0; i>1; i++) - printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i, - &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - } + if(dci_pdu->RNTI!=0xFFFF) { + for (int i=0; i>1; i++) + printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i, + &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]); + } #endif } @@ -265,7 +266,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int16_t amp, NR_DL_FRAME_PARMS *frame_parms) { - for (int i=0; inum_ul_pdcch; i++) nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot); for (int i=0; inum_dl_pdcch; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index d32fd77b03..30dbc39185 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -123,7 +123,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, rel15->dlDmrsSymbPos); n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity; } - int16_t mod_ptrs[n_ptrs<<1] __attribute__ ((aligned(16))); /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); @@ -302,12 +301,14 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, /* calculate if current symbol is PTRS symbols */ ptrs_idx = 0; - + int16_t *mod_ptrs = NULL; if(rel15->pduBitmap & 0x1) { ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos); if(ptrs_symbol) { /* PTRS QPSK Modulation for each OFDM symbol in a slot */ LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs); + int16_t mod_ptrsBuf[n_ptrs<<1] __attribute__ ((aligned(16))); + mod_ptrs =mod_ptrsBuf; nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index f0f9f4fe34..8672f3ae29 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -123,7 +123,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, bzero(dlsch,sizeof(NR_gNB_DLSCH_t)); dlsch->Kmimo = Kmimo; dlsch->Mdlharq = Mdlharq; - dlsch->Mlimit = 4; dlsch->Nsoft = Nsoft; int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index fc7df46496..278c2dfd58 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -35,6 +35,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/sse_intrin.h" +#include "executables/softmodem-common.h" //#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING @@ -248,6 +249,9 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, for (int i=0; ipbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<sa ? config->ssb_table.ssb_subcarrier_offset.value : 31; + #ifdef DEBUG_PBCH_ENCODING for (int i=0; i<3; i++) printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]); @@ -265,7 +269,7 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, for (int i=0; i<3; i++) pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index else - pbch->pbch_a |= ((config->ssb_table.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) + pbch->pbch_a |= ((ssb_sc_offset>>4)&1)<<29; //MSB of k_SSB (bit index 4) LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index e3b7efacfb..5437a9bb81 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -121,11 +121,11 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB, const NR_DL_FRAME_ @param slot Slot number @param harq_pid HARQ process ID */ -int nr_rx_pusch(PHY_VARS_gNB *gNB, - uint8_t UE_id, - uint32_t frame, - uint8_t slot, - unsigned char harq_pid); +void nr_rx_pusch(PHY_VARS_gNB *gNB, + uint8_t UE_id, + uint32_t frame, + uint8_t slot, + unsigned char harq_pid); /** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented) @param rxdataF pointer to the received frequency domain signal @@ -330,19 +330,27 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t **srs_received_signal); + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)]); void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); void free_nr_ru_prach_entry(RU_t *ru, int prach_id); uint8_t get_nr_prach_duration(uint8_t prach_format); -void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, +void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, - int16_t amp, - nr_csi_rs_info_t *nr_csi_rs_info, - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, - int slot); + const int16_t amp, + nr_csi_info_t *nr_csi_info, + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, + const int slot, + uint8_t *N_cdm_groups, + uint8_t *CDM_group_size, + uint8_t *k_prime, + uint8_t *l_prime, + uint8_t *N_ports, + uint8_t *j_cdm, + uint8_t *k_overline, + uint8_t *l_overline); void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); @@ -362,6 +370,7 @@ void nr_decode_pucch1(int32_t **rxdataF, uint8_t nr_bit); void nr_decode_pucch2(PHY_VARS_gNB *gNB, + int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); @@ -372,10 +381,5 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); -void nr_decode_pucch2(PHY_VARS_gNB *gNB, - int slot, - nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, - nfapi_nr_pucch_pdu_t* pucch_pdu); - #endif /*__NR_TRANSPORT__H__*/ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 5c6839366c..e56a4607e2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -68,12 +68,20 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, ulsch->rnti = ulsch_pdu->rnti; //ulsch->rnti_type; ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid; - ulsch->harq_processes[harq_pid]->frame=frame; - ulsch->harq_processes[harq_pid]->slot=slot; - ulsch->harq_processes[harq_pid]->handled= 0; - ulsch->harq_processes[harq_pid]->status= NR_ACTIVE; + NR_UL_gNB_HARQ_t *harq = ulsch->harq_processes[harq_pid]; + harq->frame=frame; + harq->slot=slot; + harq->handled = 0; + harq->status= NR_ACTIVE; + harq->new_rx = harq->ndi != ulsch_pdu->pusch_data.new_data_indicator; + if (harq->new_rx) { + harq->ndi = ulsch_pdu->pusch_data.new_data_indicator; + harq->round = 0; + } else { + harq->round++; + } + memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t)); LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 355dbafc6f..424630a192 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -102,7 +102,6 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t)); ulsch->max_ldpc_iterations = max_ldpc_iterations; - ulsch->Mlimit = 4; for (i=0; irnti_type = 0; ulsch->cyclicShift = 0; ulsch->cooperation_flag = 0; - ulsch->Mlimit = 0; ulsch->max_ldpc_iterations = 0; ulsch->last_iteration_cnt = 0; - for (i=0;iharq_process_id[i] = 0; for (i=0; iharq_processes[i]){ @@ -433,7 +430,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t n_layers = pusch_pdu->nrOfLayers; // ------------------------------------------------------------------ - if (!ulsch_llr) { + if (!ulsch_llr) { LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n"); return 1; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 4b8315e1ce..ac4c6f35e0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1891,11 +1891,11 @@ uint8_t nr_ulsch_zero_forcing_rx_2layers(int **rxdataF_comp, //============================================================================================== /* Main Function */ -int nr_rx_pusch(PHY_VARS_gNB *gNB, - uint8_t ulsch_id, - uint32_t frame, - uint8_t slot, - unsigned char harq_pid) +void nr_rx_pusch(PHY_VARS_gNB *gNB, + uint8_t ulsch_id, + uint32_t frame, + uint8_t slot, + unsigned char harq_pid) { uint8_t aarx, aatx; @@ -2149,6 +2149,4 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol]; } } // symbol loop - - return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 5617b8e58b..2f8a288c66 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -278,16 +278,30 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uint8_t maxpos=0; uint8_t index=0; + int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1 + int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch],*tmp_rp; + for (int l=0; lnr_of_symbols; l++) { l2 = l+pucch_pdu->start_symbol_index; + re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset; if (re_offset[l]>= frame_parms->ofdm_symbol_size) re_offset[l]-=frame_parms->ofdm_symbol_size; - - AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n"); + for (int aa=0;aanb_antennas_rx;aa++) { - c16_t *r=(c16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]]; - for (n=0;n<12;n++) { + tmp_rp = &rxdataF[aa][soffset + l2*frame_parms->ofdm_symbol_size]; + if(re_offset[l] + nb_re_pucch > frame_parms->ofdm_symbol_size) { + int neg_length = frame_parms->ofdm_symbol_size-re_offset[l]; + int pos_length = nb_re_pucch-neg_length; + memcpy1((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],neg_length*sizeof(int32_t)); + memcpy1((void*)&rp[aa][l][neg_length],(void*)tmp_rp,pos_length*sizeof(int32_t)); + } + else + memcpy1((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],nb_re_pucch*sizeof(int32_t)); + + c16_t *r = (c16_t*)&rp[aa][l]; + + for (n=0;n>= 31; - corr[aa][l].i >>= 31; + corr[aa][l].r >>= 31; + corr[aa][l].i >>= 31; } } LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n", @@ -385,9 +399,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]); int SNRtimes10,sigenergy=0; for (int aa=0;aanb_antennas_rx;aa++) - sigenergy += signal_energy_nodc(&rxdataF[aa][soffset+ - (pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size)+ - re_offset[0]],12); + sigenergy += signal_energy_nodc(rp[aa][0],12); SNRtimes10 = xrtmag_dBtimes10-(10*max_n0); int cqi; if (SNRtimes10 < -640) cqi=0; @@ -1124,6 +1136,7 @@ void init_pucch2_luts() { void nr_decode_pucch2(PHY_VARS_gNB *gNB, + int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu) { @@ -1708,13 +1721,19 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->pduBitmap|=2; uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes); uci_pdu->harq.harq_crc = decoderState; + LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ bytes (%d) Decoder state %d\n", + frame,slot,harq_bytes,decoderState); int i=0; for (;iharq.harq_payload[i] = decodedPayload[0] & 255; + LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ paylod (%d) = %d\n", + frame,slot,i,uci_pdu->harq.harq_payload[i]); decodedPayload[0]>>=8; } bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3); uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<harq.harq_payload[i]); decodedPayload[0] >>= pucch_pdu->bit_len_harq; } diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 2d7aefdee0..39c3846db5 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -98,7 +98,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t **srs_received_signal) { + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)]) { if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); @@ -113,6 +113,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; int32_t *rx_signal; + bool no_srs_signal = true; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); @@ -121,6 +122,10 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] = rx_signal[nr_srs_info->sc_list[sc_idx]]; + if (rx_signal[nr_srs_info->sc_list[sc_idx]] != 0) { + no_srs_signal = false; + } + #ifdef SRS_DEBUG uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; @@ -140,5 +145,11 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, #endif } } - return 0; + + if (no_srs_signal) { + LOG_W(NR_PHY, "No SRS signal\n"); + return -1; + } else { + return 0; + } } \ No newline at end of file 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 8936a69e70..ba7e61afe6 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1657,7 +1657,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, RX_type_t rx_type) { //#define DEBUG_DL_PTRS 1 - int16_t *phase_per_symbol = NULL; int32_t *ptrs_re_symbol = NULL; int8_t ret = 0; /* harq specific variables */ @@ -1701,20 +1700,20 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } /* loop over antennas */ for (int aarx=0; aarxnb_antennas_rx; aarx++) { - phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; + c16_t *phase_per_symbol = (c16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx]; ptrs_re_symbol[symbol] = 0; - phase_per_symbol[(2*symbol)+1] = 0; // Imag + phase_per_symbol[symbol].i = 0; // Imag /* set DMRS estimates to 0 angle with magnitude 1 */ if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { /* set DMRS real estimation to 32767 */ - phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 + phase_per_symbol[symbol].r=INT16_MAX; // 32767 #ifdef DEBUG_DL_PTRS - printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i); #endif } else { // real ptrs value is set to 0 - phase_per_symbol[2*symbol] = 0; // Real + phase_per_symbol[symbol].r = 0; // Real } if(dlsch0_harq->status == ACTIVE) { @@ -1740,7 +1739,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0], - &phase_per_symbol[2* symbol], + (int16_t*)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); } }// HARQ 0 @@ -1752,7 +1751,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /*------------------------------------------------------------------------------------------------------- */ /* If L-PTRS is > 0 then we need interpolation */ if(*L_ptrs > 0) { - ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb); if(ret != 0) { LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } @@ -1771,11 +1770,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /* Skip rotation if the slot processing is wrong */ if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_DL_PTRS - printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); + printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], - &phase_per_symbol[2* i], - (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + &phase_per_symbol[i], + (c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 79fd7a3dd2..43944b2fa8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -33,16 +33,103 @@ #include #include +#include "executables/nr-softmodem-common.h" #include "nr_transport_proto_ue.h" #include "PHY/phy_extern_nr_ue.h" #include "common/utils/nr/nr_common.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" +// 10*log10(pow(2,30)) +#define pow_2_30_dB 90 //#define NR_CSIRS_DEBUG +//#define NR_CSIIM_DEBUG -bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) { +void nr_det_A_MF_2x2(int32_t *a_mf_00, + int32_t *a_mf_01, + int32_t *a_mf_10, + int32_t *a_mf_11, + int32_t *det_fin, + const unsigned short nb_rb) { + + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + + __m128i ad_re_128, bc_re_128, det_re_128; + + __m128i *a_mf_00_128 = (__m128i *)a_mf_00; + __m128i *a_mf_01_128 = (__m128i *)a_mf_01; + __m128i *a_mf_10_128 = (__m128i *)a_mf_10; + __m128i *a_mf_11_128 = (__m128i *)a_mf_11; + __m128i *det_fin_128 = (__m128i *)det_fin; + + for (int rb = 0; rb<3*nb_rb; rb++) { + + //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d) + //The imag part is often zero, we compute only the real part + ad_re_128 = _mm_sign_epi16(a_mf_00_128[0],*(__m128i*)&nr_conjug2[0]); + ad_re_128 = _mm_madd_epi16(ad_re_128,a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 + + //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c) + //The imag part is often zero, we compute only the real part + bc_re_128 = _mm_sign_epi16(a_mf_01_128[0],*(__m128i*)&nr_conjug2[0]); + bc_re_128 = _mm_madd_epi16(bc_re_128,a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 + + det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128); + + //det in Q30 format + det_fin_128[0] = _mm_abs_epi32(det_re_128); + + det_fin_128+=1; + a_mf_00_128+=1; + a_mf_01_128+=1; + a_mf_10_128+=1; + a_mf_11_128+=1; + } + _mm_empty(); + _m_empty(); +} + +void nr_squared_matrix_element(int32_t *a, + int32_t *a_sq, + const unsigned short nb_rb) { + __m128i *a_128 = (__m128i *)a; + __m128i *a_sq_128 = (__m128i *)a_sq; + for (int rb=0; rb<3*nb_rb; rb++) { + a_sq_128[0] = _mm_madd_epi16(a_128[0], a_128[0]); + a_sq_128+=1; + a_128+=1; + } + _mm_empty(); + _m_empty(); +} + +void nr_numer_2x2(int32_t *a_00_sq, + int32_t *a_01_sq, + int32_t *a_10_sq, + int32_t *a_11_sq, + int32_t *num_fin, + const unsigned short nb_rb) { + __m128i *a_00_sq_128 = (__m128i *)a_00_sq; + __m128i *a_01_sq_128 = (__m128i *)a_01_sq; + __m128i *a_10_sq_128 = (__m128i *)a_10_sq; + __m128i *a_11_sq_128 = (__m128i *)a_11_sq; + __m128i *num_fin_128 = (__m128i *)num_fin; + for (int rb=0; rb<3*nb_rb; rb++) { + __m128i sq_a_plus_sq_d_128 = _mm_add_epi32(a_00_sq_128[0], a_11_sq_128[0]); + __m128i sq_b_plus_sq_c_128 = _mm_add_epi32(a_01_sq_128[0], a_10_sq_128[0]); + num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128); + num_fin_128+=1; + a_00_sq_128+=1; + a_01_sq_128+=1; + a_10_sq_128+=1; + a_11_sq_128+=1; + } + _mm_empty(); + _m_empty(); +} + +bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, const int symbol) { bool ret = false; @@ -90,17 +177,27 @@ bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, i return ret; } -int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - nr_csi_rs_info_t *nr_csi_rs_info, - int32_t **csi_rs_received_signal) { +int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_cdm_groups, + const uint8_t CDM_group_size, + const uint8_t k_prime, + const uint8_t l_prime, + const uint8_t *j_cdm, + const uint8_t *k_overline, + const uint8_t *l_overline, + int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], + uint32_t *rsrp, + int *rsrp_dBm) { int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + uint16_t meas_count = 0; + uint32_t rsrp_sum = 0; for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { - memset(csi_rs_received_signal[ant_rx], 0, frame_parms->samples_per_frame_wCP*sizeof(int32_t)); for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -109,36 +206,41 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, continue; } - for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) { - for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) { + for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) { + for (int s = 0; s < CDM_group_size; s++) { // loop over frequency resource elements within a group - for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) { + for (int kp = 0; kp <= k_prime; kp++) { - uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+nr_csi_rs_info->koverline[cdm_id] + kp) % frame_parms->ofdm_symbol_size; + uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+k_overline[cdm_id] + kp) % frame_parms->ofdm_symbol_size; // loop over time resource elements within a group - for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) { - uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id]; + for (int lp = 0; lp <= l_prime; lp++) { + uint16_t symb = lp + l_overline[cdm_id]; uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - int16_t *rx_signal = (int16_t*)&rxdataF[ant_rx][symbol_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - rx_csi_rs_signal[k<<1] = rx_signal[k<<1]; - rx_csi_rs_signal[(k<<1)+1] = rx_signal[(k<<1)+1]; + c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + rx_csi_rs_signal[k].r = rx_signal[k].r; + rx_csi_rs_signal[k].i = rx_signal[k].i; + + rsrp_sum += (((int32_t)(rx_csi_rs_signal[k].r)*rx_csi_rs_signal[k].r) + + ((int32_t)(rx_csi_rs_signal[k].i)*rx_csi_rs_signal[k].i)); + + meas_count++; #ifdef NR_CSIRS_DEBUG int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; - uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size; - int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size; + c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n", symb, k, port_tx+3000, - tx_csi_rs_signal[k<<1], - tx_csi_rs_signal[(k<<1)+1], + tx_csi_rs_signal[k].r, + tx_csi_rs_signal[k].i, ant_rx, - rx_csi_rs_signal[k<<1], - rx_csi_rs_signal[(k<<1)+1]); + rx_csi_rs_signal[k].r, + rx_csi_rs_signal[k].i); #endif } } @@ -147,10 +249,19 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, } } + + *rsrp = rsrp_sum/meas_count; + *rsrp_dBm = dB_fixed(*rsrp) + 30 - pow_2_30_dB + - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm); +#endif + return 0; } -uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) { +uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) { uint64_t sum_x = 0; uint64_t sum_x2 = 0; uint16_t size = 0; @@ -165,25 +276,38 @@ uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csir return sum_x2/size - (sum_x/size)*(sum_x/size); } -int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - nr_csi_rs_info_t *nr_csi_rs_info, - int32_t **csi_rs_generated_signal, - int32_t **csi_rs_received_signal, - int32_t ***csi_rs_estimated_channel_freq, +int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const int32_t **csi_rs_generated_signal, + const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], + const uint8_t N_cdm_groups, + const uint8_t CDM_group_size, + const uint8_t k_prime, + const uint8_t l_prime, + const uint8_t N_ports, + const uint8_t *j_cdm, + const uint8_t *k_overline, + const uint8_t *l_overline, + int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size], + int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + int16_t *log2_re, + int16_t *log2_maxh, uint32_t *noise_power) { - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; *noise_power = 0; + int maxh = 0; + int count = 0; for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { /// LS channel estimation - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { - memset(nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); + for(uint16_t port_tx = 0; port_txofdm_symbol_size*sizeof(int32_t)); } for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -193,32 +317,32 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, continue; } - for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) { - for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) { + for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) { + for (int s = 0; s < CDM_group_size; s++) { - uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size; + uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size; // loop over frequency resource elements within a group - for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) { + for (int kp = 0; kp <= k_prime; kp++) { uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - uint16_t k = kinit + nr_csi_rs_info->koverline[cdm_id] + kp; + uint16_t k = kinit + k_overline[cdm_id] + kp; // loop over time resource elements within a group - for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) { - uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id]; + for (int lp = 0; lp <= l_prime; lp++) { + uint16_t symb = lp + l_overline[cdm_id]; uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); - int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); + int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits); + int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_info->csi_rs_generated_signal_bits); // This is not just the LS estimation for each (k,l), but also the sum of the different contributions // for the sake of optimizing the memory used. - csi_rs_ls_estimated_channel[kinit<<1] += csi_rs_ls_estimated_channel_re; - csi_rs_ls_estimated_channel[(kinit<<1)+1] += csi_rs_ls_estimated_channel_im; + csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re; + csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im; } } } @@ -232,16 +356,16 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, } for(int k = 0; kofdm_symbol_size; k++) { LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k); - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { + for(uint16_t port_tx = 0; port_txofdm_symbol_size; - int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ", port_tx+3000, ant_rx, - tx_csi_rs_signal[k<<1], tx_csi_rs_signal[(k<<1)+1], - rx_csi_rs_signal[k<<1], rx_csi_rs_signal[(k<<1)+1], - csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]); + tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i, + rx_csi_rs_signal[k].r, rx_csi_rs_signal[k].i, + csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i); } printf("\n"); } @@ -250,7 +374,7 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, /// Channel interpolation - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { + for(uint16_t port_tx = 0; port_txofdm_symbol_size*sizeof(int32_t)); } @@ -261,37 +385,40 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, continue; } + count++; + uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; + for(uint16_t port_tx = 0; port_txfirst_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case - multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16, 24); + multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24); } else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) || (rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case - multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); } else { // Middle case - multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); } } } /// Power noise estimation - uint16_t noise_real[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs]; - uint16_t noise_imag[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs]; + uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; + uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { continue; } uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; - int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k]; - noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[0]-csi_rs_estimated_channel16[0]); - noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[1]-csi_rs_estimated_channel16[1]); + for(uint16_t port_tx = 0; port_txstart_rb] = abs(csi_rs_ls_estimated_channel16->r-csi_rs_estimated_channel16->r); + noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->i-csi_rs_estimated_channel16->i); + maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i)); } } - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { + for(uint16_t port_tx = 0; port_txfirst_carrier_offset)/NR_NB_SC_PER_RB : (k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB; LOG_I(NR_PHY, "(k = %4d) |\t", k); - for(uint16_t port_tx = 0; port_txN_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0]; + for(uint16_t port_tx = 0; port_tx ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ", port_tx+3000, ant_rx, - csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1], - csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1], + csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i, + csi_rs_estimated_channel16[k].r, csi_rs_estimated_channel16[k].i, rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb], rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]); } @@ -317,7 +444,9 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, } - *noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports); + *noise_power /= (frame_parms->nb_antennas_rx*N_ports); + *log2_maxh = log2_approx(maxh-1); + *log2_re = log2_approx(count-1); #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power); @@ -326,7 +455,371 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, return 0; } +int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_ports, + int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + const int16_t log2_maxh, + uint8_t *rank_indicator) { + + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const int16_t cond_dB_threshold = 5; + int count = 0; + *rank_indicator = 0; + + if (ue->frame_parms.nb_antennas_rx == 1 || N_ports == 1) { + return 0; + } else if( !(ue->frame_parms.nb_antennas_rx == 2 && N_ports == 2) ) { + LOG_W(NR_PHY, "Rank indicator computation is not implemented for %i x %i system\n", + ue->frame_parms.nb_antennas_rx, N_ports); + return -1; + } + + /* Example 2x2: Hh x H = + * | conjch00 conjch10 | x | ch00 ch01 | = | conjch00*ch00+conjch10*ch10 conjch00*ch01+conjch10*ch11 | + * | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 | + */ + + int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_numer_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + + const uint8_t sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit + + for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { + + if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { + continue; + } + uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int ant_rx_conjch = 0; ant_rx_conjch < frame_parms->nb_antennas_rx; ant_rx_conjch++) { + for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) { + for (int ant_rx_ch = 0; ant_rx_ch < frame_parms->nb_antennas_rx; ant_rx_ch++) { + for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) { + + // conjch x ch computation + nr_conjch0_mult_ch1(&csi_rs_estimated_channel_freq[ant_rx_conjch][port_tx_conjch][k], + &csi_rs_estimated_channel_freq[ant_rx_ch][port_tx_ch][k], + &csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k], + 1, + log2_maxh); + + // construct Hh x H elements + if(ant_rx_conjch == ant_rx_ch) { + nr_a_sum_b((__m128i *)&csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k], + (__m128i *)&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k], + 1); + } + } + } + } + } + + // compute the determinant of A_MF (denominator) + nr_det_A_MF_2x2(&csi_rs_estimated_A_MF[0][0][k], + &csi_rs_estimated_A_MF[0][1][k], + &csi_rs_estimated_A_MF[1][0][k], + &csi_rs_estimated_A_MF[1][1][k], + &csi_rs_estimated_determ_fin[k], + 1); + + // compute the square of A_MF (numerator) + nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][0][k], &csi_rs_estimated_A_MF_sq[0][0][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][1][k], &csi_rs_estimated_A_MF_sq[0][1][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][0][k], &csi_rs_estimated_A_MF_sq[1][0][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][1][k], &csi_rs_estimated_A_MF_sq[1][1][k], 1); + nr_numer_2x2(&csi_rs_estimated_A_MF_sq[0][0][k], + &csi_rs_estimated_A_MF_sq[0][1][k], + &csi_rs_estimated_A_MF_sq[1][0][k], + &csi_rs_estimated_A_MF_sq[1][1][k], + &csi_rs_estimated_numer_fin[k], + 1); + +#ifdef NR_CSIRS_DEBUG + for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) { + for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) { + c16_t *csi_rs_estimated_A_MF_k = (c16_t *) &csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k]; + LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF[%i][%i] = (%i, %i)\n", + k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_k->r, csi_rs_estimated_A_MF_k->i); + c16_t *csi_rs_estimated_A_MF_sq_k = (c16_t *) &csi_rs_estimated_A_MF_sq[port_tx_conjch][port_tx_ch][k]; + LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF_sq[%i][%i] = (%i, %i)\n", + k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_sq_k->r, csi_rs_estimated_A_MF_sq_k->i); + } + } + LOG_I(NR_PHY, "(%i) csi_rs_estimated_determ_fin = %i\n", k, csi_rs_estimated_determ_fin[k]); + LOG_I(NR_PHY, "(%i) csi_rs_estimated_numer_fin = %i\n", k, csi_rs_estimated_numer_fin[k]>>sum_shift); +#endif + + // compute the conditional number + for (int sc_idx=0; sc_idx < NR_NB_SC_PER_RB; sc_idx++) { + int8_t csi_rs_estimated_denum_db = dB_fixed(csi_rs_estimated_determ_fin[k + sc_idx]); + int8_t csi_rs_estimated_numer_db = dB_fixed(csi_rs_estimated_numer_fin[k + sc_idx]>>sum_shift); + int8_t cond_db = csi_rs_estimated_numer_db - csi_rs_estimated_denum_db; + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "csi_rs_estimated_denum_db = %i\n", csi_rs_estimated_denum_db); + LOG_I(NR_PHY, "csi_rs_estimated_numer_db = %i\n", csi_rs_estimated_numer_db); + LOG_I(NR_PHY, "cond_db = %i\n", cond_db); +#endif + + if (cond_db < cond_dB_threshold) { + count++; + } else { + count--; + } + } + } + + // conditional number is lower than cond_dB_threshold in half on more REs + if (count > 0) { + *rank_indicator = 1; + } + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "count = %i\n", count); + LOG_I(NR_PHY, "rank = %i\n", (*rank_indicator)+1); +#endif + + return 0; +} + +int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_ports, + const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + const uint32_t interference_plus_noise_power, + const uint8_t rank_indicator, + const int16_t log2_re, + uint8_t *i1, + uint8_t *i2, + uint32_t *precoded_sinr_dB) { + + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + memset(i1,0,3*sizeof(uint8_t)); + i2[0] = 0; + + // i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'. + // Note that i13 is not applicable when the number of transmission layers is one of {1, 5, 6, 7, 8}. + // i2, for 'Type1SinglePanel' codebook type, it is a scalar when PMIMode is specified as 'wideband', and when PMIMode + // is specified as 'subband' or when PRGSize, the length of the i2 vector equals to the number of subbands or PRGs. + // Note that when the number of CSI-RS ports is 2, the applicable codebook type is 'Type1SinglePanel'. In this case, + // the precoding matrix is obtained by a single index (i2 field here) based on TS 38.214 Table 5.2.2.2.1-1. + // The first column is applicable if the UE is reporting a Rank = 1, whereas the second column is applicable if the + // UE is reporting a Rank = 2. + + if(N_ports == 1 || interference_plus_noise_power == 0) { + return 0; + } + + if(rank_indicator == 0 || rank_indicator == 1) { + + int32_t sum_re[4] = {0}; + int32_t sum_im[4] = {0}; + int32_t sum2_re[4] = {0}; + int32_t sum2_im[4] = {0}; + int32_t tested_precoded_sinr[4] = {0}; + + for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { + + if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { + continue; + } + uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + + c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k]; + c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k]; + + // H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im) + sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r); + sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i); + sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re; + sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re; + + // H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re) + sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i); + sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r); + sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re; + sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re; + + // H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im) + sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r); + sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i); + sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re; + sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re; + + // H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re) + sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i); + sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r); + sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re; + sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re; + } + } + + // We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values, + // we performed this above. + for(int p = 0; p<4; p++) { + int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re); + int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re); + tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power; + } + + if(rank_indicator == 0) { + for(int tested_i2 = 0; tested_i2 < 4; tested_i2++) { + if(tested_precoded_sinr[tested_i2] > tested_precoded_sinr[i2[0]]) { + i2[0] = tested_i2; + } + } + *precoded_sinr_dB = dB_fixed(tested_precoded_sinr[i2[0]]); + } else { + i2[0] = tested_precoded_sinr[0]+tested_precoded_sinr[2] > tested_precoded_sinr[1]+tested_precoded_sinr[3] ? 0 : 1; + *precoded_sinr_dB = dB_fixed((tested_precoded_sinr[i2[0]] + tested_precoded_sinr[i2[0]+2])>>1); + } + + } else { + LOG_W(NR_PHY, "PMI computation is not implemented for rank indicator %i\n", rank_indicator+1); + return -1; + } + + return 0; +} + +int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, + uint8_t *cqi) { + + *cqi = 0; + + // Default SINR table for an AWGN channel for SISO scenario, considering 0.1 BLER condition and TS 38.214 Table 5.2.2.1-2 + if(precoded_sinr>0 && precoded_sinr<=2) { + *cqi = 4; + } else if(precoded_sinr==3) { + *cqi = 5; + } else if(precoded_sinr>3 && precoded_sinr<=5) { + *cqi = 6; + } else if(precoded_sinr>5 && precoded_sinr<=7) { + *cqi = 7; + } else if(precoded_sinr>7 && precoded_sinr<=9) { + *cqi = 8; + } else if(precoded_sinr==10) { + *cqi = 9; + } else if(precoded_sinr>10 && precoded_sinr<=12) { + *cqi = 10; + } else if(precoded_sinr>12 && precoded_sinr<=15) { + *cqi = 11; + } else if(precoded_sinr==16) { + *cqi = 12; + } else if(precoded_sinr>16 && precoded_sinr<=18) { + *cqi = 13; + } else if(precoded_sinr==19) { + *cqi = 14; + } else if(precoded_sinr>19) { + *cqi = 15; + } + + return 0; +} + +int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, + uint32_t *interference_plus_noise_power) { + + int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + + const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ? + csiim_config_pdu->bwp_size : csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs; + + int32_t count = 0; + int32_t sum_re = 0; + int32_t sum_im = 0; + int32_t sum2_re = 0; + int32_t sum2_im = 0; + + int l_csiim[4] = {-1, -1, -1, -1}; + + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + + uint8_t symb = csiim_config_pdu->l_csiim[symb_idx]; + bool done = false; + for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { + if (l_csiim[symb_idx2] == symb) { + done = true; + } + } + + if (done) { + continue; + } + + l_csiim[symb_idx] = symb; + uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; + + for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + + c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + + for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) { + + uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int sc_idx = 0; sc_idx<4; sc_idx++) { + + uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx]; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "(ant_rx %i, sc %i) real %i, imag %i\n", ant_rx, rb, rx_signal[sc].r, rx_signal[sc].i); +#endif + + sum_re += rx_signal[sc].r; + sum_im += rx_signal[sc].i; + sum2_re += rx_signal[sc].r*rx_signal[sc].r; + sum2_im += rx_signal[sc].i*rx_signal[sc].i; + count++; + } + } + } + } + + int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count); + int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count); + + *interference_plus_noise_power = power_re + power_im; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_noise_power); +#endif + + return 0; +} + int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { + + if(!ue->csiim_vars[gNB_id]->active) { + return -1; + } + + const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = (fapi_nr_dl_config_csiim_pdu_rel15_t*)&ue->csiim_vars[gNB_id]->csiim_config_pdu; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "csiim_config_pdu->bwp_size = %i\n", csiim_config_pdu->bwp_size); + LOG_I(NR_PHY, "csiim_config_pdu->bwp_start = %i\n", csiim_config_pdu->bwp_start); + LOG_I(NR_PHY, "csiim_config_pdu->subcarrier_spacing = %i\n", csiim_config_pdu->subcarrier_spacing); + LOG_I(NR_PHY, "csiim_config_pdu->start_rb = %i\n", csiim_config_pdu->start_rb); + LOG_I(NR_PHY, "csiim_config_pdu->nr_of_rbs = %i\n", csiim_config_pdu->nr_of_rbs); + LOG_I(NR_PHY, "csiim_config_pdu->k_csiim = %i.%i.%i.%i\n", csiim_config_pdu->k_csiim[0], csiim_config_pdu->k_csiim[1], csiim_config_pdu->k_csiim[2], csiim_config_pdu->k_csiim[3]); + LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); +#endif + + nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power); + ue->nr_csi_info->csi_im_meas_computed = true; + return 0; } @@ -336,7 +829,7 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t return -1; } - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu; + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu; #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing); @@ -355,26 +848,122 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss); #endif - nr_generate_csi_rs(ue->frame_parms, - ue->nr_csi_rs_info->csi_rs_generated_signal, + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP]; + uint8_t N_cdm_groups = 0; + uint8_t CDM_group_size = 0; + uint8_t k_prime = 0; + uint8_t l_prime = 0; + uint8_t N_ports = 0; + uint8_t j_cdm[16]; + uint8_t k_overline[16]; + uint8_t l_overline[16]; + int16_t log2_re = 0; + int16_t log2_maxh = 0; + uint32_t rsrp = 0; + int rsrp_dBm = 0; + uint32_t noise_power = 0; + uint8_t rank_indicator = 0; + uint32_t precoded_sinr_dB = 0; + uint8_t cqi = 0; + uint8_t i1[3]; + uint8_t i2[1]; + + nr_generate_csi_rs(frame_parms, + ue->nr_csi_info->csi_rs_generated_signal, AMP, - ue->nr_csi_rs_info, + ue->nr_csi_info, (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu, - proc->nr_slot_rx); + proc->nr_slot_rx, + &N_cdm_groups, + &CDM_group_size, + &k_prime, + &l_prime, + &N_ports, + j_cdm, + k_overline, + l_overline); + + int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size]; + int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size]; nr_get_csi_rs_signal(ue, proc, csirs_config_pdu, - ue->nr_csi_rs_info, - ue->nr_csi_rs_info->csi_rs_received_signal); + ue->nr_csi_info, + N_cdm_groups, + CDM_group_size, + k_prime, + l_prime, + j_cdm, + k_overline, + l_overline, + csi_rs_received_signal, + &rsrp, + &rsrp_dBm); nr_csi_rs_channel_estimation(ue, proc, csirs_config_pdu, - ue->nr_csi_rs_info, - ue->nr_csi_rs_info->csi_rs_generated_signal, - ue->nr_csi_rs_info->csi_rs_received_signal, - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq, - ue->nr_csi_rs_info->noise_power); + ue->nr_csi_info, + (const int32_t **) ue->nr_csi_info->csi_rs_generated_signal, + csi_rs_received_signal, + N_cdm_groups, + CDM_group_size, + k_prime, + l_prime, + N_ports, + j_cdm, + k_overline, + l_overline, + csi_rs_ls_estimated_channel, + csi_rs_estimated_channel_freq, + &log2_re, + &log2_maxh, + &noise_power); + + nr_csi_rs_ri_estimation(ue, + csirs_config_pdu, + ue->nr_csi_info, + N_ports, + csi_rs_estimated_channel_freq, + log2_maxh, + &rank_indicator); + + nr_csi_rs_pmi_estimation(ue, + csirs_config_pdu, + ue->nr_csi_info, + N_ports, + csi_rs_estimated_channel_freq, + ue->nr_csi_info->csi_im_meas_computed ? ue->nr_csi_info->interference_plus_noise_power : noise_power, + rank_indicator, + log2_re, + i1, + i2, + &precoded_sinr_dB); + + nr_csi_rs_cqi_estimation(precoded_sinr_dB, &cqi); + + LOG_I(NR_PHY, "RSRP = %i dBm, RI = %i, i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n", + rsrp_dBm, rank_indicator+1, i1[0], i1[1], i1[2], i2[0], precoded_sinr_dB, cqi); + + // Send CSI measurements to MAC + fapi_nr_csirs_measurements_t csirs_measurements; + csirs_measurements.rsrp = rsrp; + csirs_measurements.rsrp_dBm = rsrp_dBm; + csirs_measurements.rank_indicator = rank_indicator; + csirs_measurements.i1 = *i1; + csirs_measurements.i2 = *i2; + csirs_measurements.cqi = cqi; + nr_downlink_indication_t dl_indication; + fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL); + nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements); + if (ue->if_inst && ue->if_inst->dl_indication) { + ue->if_inst->dl_indication(&dl_indication, NULL); + } else { + free(rx_ind); + } + return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 403f016e79..1635c8bba9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -140,7 +140,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint dlsch->Mdlharq = Mdlharq; dlsch->number_harq_processes_for_pdsch = Mdlharq; dlsch->Nsoft = Nsoft; - dlsch->Mlimit = 4; dlsch->max_ldpc_iterations = max_ldpc_iterations; for (int i=0; iround %d\n", // phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); harq_process->status = SCH_IDLE; - harq_process->DLround = 0; harq_process->ack = 1; //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", @@ -237,11 +235,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool //LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", // phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); harq_process->ack = 0; - if (harq_process->DLround >= dlsch->Mlimit) { - harq_process->status = SCH_IDLE; - harq_process->DLround = 0; - phy_vars_ue->dl_stats[4]++; - } //if(is_crnti) { // LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", @@ -496,8 +489,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } */ nb_rb = harq_process->nb_rb; - harq_process->trials[harq_process->DLround]++; - A = harq_process->TBS; ret = dlsch->max_ldpc_iterations + 1; dlsch->last_iteration_cnt = ret; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index eb43d80525..6728f0260c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -466,88 +466,87 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (cpumeas(CPUMEAS_GETSTATE)) LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); - start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); /* Store the valid DL RE's */ - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch; + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch; - if(dlsch0_harq->status == ACTIVE) { - startSymbIdx = dlsch0_harq->start_symbol; - nbSymb = dlsch0_harq->nb_symbols; - pduBitmap = dlsch0_harq->pduBitmap; - } - if(dlsch1_harq) { - startSymbIdx = dlsch1_harq->start_symbol; - nbSymb = dlsch1_harq->nb_symbols; - pduBitmap = dlsch1_harq->pduBitmap; - } + if(dlsch0_harq->status == ACTIVE) { + startSymbIdx = dlsch0_harq->start_symbol; + nbSymb = dlsch0_harq->nb_symbols; + pduBitmap = dlsch0_harq->pduBitmap; + } + if(dlsch1_harq) { + startSymbIdx = dlsch1_harq->start_symbol; + nbSymb = dlsch1_harq->nb_symbols; + pduBitmap = dlsch1_harq->pduBitmap; + } - /* Check for PTRS bitmap and process it respectively */ - if((pduBitmap & 0x1) && (type == PDSCH)) { - nr_pdsch_ptrs_processing(ue, - pdsch_vars, - frame_parms, - dlsch0_harq, - dlsch1_harq, - gNB_id, - nr_slot_rx, - symbol, - (nb_rb_pdsch*12), - dlsch[0]->rnti,rx_type); - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; - } + /* Check for PTRS bitmap and process it respectively */ + if((pduBitmap & 0x1) && (type == PDSCH)) { + nr_pdsch_ptrs_processing(ue, + pdsch_vars, + frame_parms, + dlsch0_harq, + dlsch1_harq, + gNB_id, + nr_slot_rx, + symbol, + (nb_rb_pdsch*12), + dlsch[0]->rnti,rx_type); + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; + } - /* at last symbol in a slot calculate LLR's for whole slot */ - if(symbol == (startSymbIdx + nbSymb -1)) { - for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { - /* re evaluating the first symbol flag as LLR's are done in symbol loop */ - if(i == startSymbIdx && i < 3) { - first_symbol_flag =1; - } - else { - first_symbol_flag=0; - } - /* Calculate LLR's for each symbol */ - nr_dlsch_llr(pdsch_vars, frame_parms, - rxdataF_comp_ptr, dl_ch_mag_ptr, - dlsch0_harq, dlsch1_harq, - rx_type, harq_pid, - gNB_id, gNB_id_i, - first_symbol_flag, - i, nb_rb_pdsch, - codeword_TB0, codeword_TB1, - pdsch_vars[gNB_id]->dl_valid_re[i-1], - nr_slot_rx, beamforming_mode); + /* at last symbol in a slot calculate LLR's for whole slot */ + if(symbol == (startSymbIdx + nbSymb -1)) { + for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { + /* re evaluating the first symbol flag as LLR's are done in symbol loop */ + if(i == startSymbIdx && i < 3) { + first_symbol_flag =1; } - - int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType; - uint8_t nb_re_dmrs; - uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos); - if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; - } else { - nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + else { + first_symbol_flag=0; } - dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb, - dlsch[0]->harq_processes[harq_pid]->nb_symbols, - nb_re_dmrs, - dmrs_len, - dlsch[0]->harq_processes[harq_pid]->Qm, - dlsch[0]->harq_processes[harq_pid]->Nl); - nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, - dlsch[0]->harq_processes[harq_pid]->Nl, - dlsch[0]->harq_processes[harq_pid]->Qm, - dlsch[0]->harq_processes[harq_pid]->G, - codeword_TB0, - codeword_TB1, - pdsch_vars[gNB_id]->layer_llr); - + /* Calculate LLR's for each symbol */ + nr_dlsch_llr(pdsch_vars, frame_parms, + rxdataF_comp_ptr, dl_ch_mag_ptr, + dlsch0_harq, dlsch1_harq, + rx_type, harq_pid, + gNB_id, gNB_id_i, + first_symbol_flag, + i, nb_rb_pdsch, + codeword_TB0, codeword_TB1, + pdsch_vars[gNB_id]->dl_valid_re[i-1], + nr_slot_rx, beamforming_mode); } - stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); - if (cpumeas(CPUMEAS_GETSTATE)) - LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); + int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType; + uint8_t nb_re_dmrs; + uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos); + if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } else { + nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } + dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb, + dlsch[0]->harq_processes[harq_pid]->nb_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->Nl); + nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, + dlsch[0]->harq_processes[harq_pid]->Nl, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->G, + codeword_TB0, + codeword_TB1, + pdsch_vars[gNB_id]->layer_llr); + } -// Please keep it: useful for debugging + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); + if (cpumeas(CPUMEAS_GETSTATE)) + LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); + + // Please keep it: useful for debugging #ifdef DEBUG_PDSCH_RX char filename[50]; uint8_t aa = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5f3af5bb39..ea7bde5377 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -362,7 +362,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]); } - nr_init_csi_rs(fp, ue->nr_csi_rs_info->nr_gold_csi_rs, fp->Nid_cell); + nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); // initialize the pusch dmrs for (int i=0; inumber_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES; - ulsch->Mlimit = 4; // maximum harq retransmissions - - //for (i=0; i<10; i++) - //ulsch->harq_ids[i] = 0; for (int i = 0; i < number_of_harq_pids; i++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index a07a19d085..eaeffd0809 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -597,17 +597,15 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; for(ap = 0; ap < n_antenna_ports; ap++) { for (int s=0;ssymbol_rotation[1])[s + symb_offset]; + LOG_D(PHY,"rotating txdataF symbol %d (%d) => (%d.%d)\n", + s, + s + symb_offset, + rot.r, rot.i); - LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n", - __FUNCTION__, - s, - s + symb_offset, - frame_parms->symbol_rotation[1][2 * (s + symb_offset)], - frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]); - - rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], - &frame_parms->symbol_rotation[1][2 * (s + symb_offset)], - (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + rotate_cpx_vector((c16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + &rot, + (c16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], frame_parms->ofdm_symbol_size, 15); } diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c index da1acb5175..d3397b033f 100644 --- a/openair1/PHY/TOOLS/calibration_scope.c +++ b/openair1/PHY/TOOLS/calibration_scope.c @@ -34,7 +34,7 @@ typedef struct OAIgraph { int h; int waterFallh; double *waterFallAvg; - boolean_t initDone; + bool initDone; int iteration; void (*funct) (struct OAIgraph *graph, calibData_t *); } OAIgraph_t; @@ -159,7 +159,7 @@ static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len *y=old_y; } -static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, bool NoAutoScale) { fl_redraw_object(graph->graph); if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index dc57964ca5..a9d502b9eb 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -144,207 +144,10 @@ void multadd_real_four_symbols_vector_complex_scalar(int16_t *x, _m_empty(); } - -/* -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift, - uint8_t format) -{ - // Multiply elementwise two complex vectors of N elements - // x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // We assume x1 with a dynamic of 15 bit maximum - // - // alpha - input 2 in the format |Re0 Im0| - // We assume x2 with a dynamic of 15 bit maximum - // - // y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // output_shift - shift at output to return in Q1.15 - // format - 0 means alpha is in shuffled format, 1 means x is in shuffled format - - uint32_t i; // loop counter - - register __m128i m0,m1; - - - - __m128i *x_128; - __m128i *y_128; - - - shift = _mm_cvtsi32_si128(output_shift); - x_128 = (__m128i *)&x[0]; - - if (format==0) { // alpha is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; - } else { // input is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; - } - - y_128 = (__m128i *)&y[0]; - - // _mm_empty(); - // return(0); - - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>3); i++) { - - m0 = _mm_madd_epi16(x_128[0],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1=m0; - m0 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[0] = _mm_unpacklo_epi32(m0,m0); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[1],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[1] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[2],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[2] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[3],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[3] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e - - y_128[0] = _mm_shufflelo_epi16(y_128[0],0x1e); - y_128[0] = _mm_shufflehi_epi16(y_128[0],0x1e); - ((int16_t*)&y_128[0])[1] = -((int16_t*)&y_128[0])[1]; - ((int16_t*)&y_128[0])[5] = -((int16_t*)&y_128[0])[5]; - y_128[1] = _mm_shufflelo_epi16(y_128[1],0x1e); - y_128[1] = _mm_shufflehi_epi16(y_128[1],0x1e); - ((int16_t*)&y_128[1])[1] = -((int16_t*)&y_128[1])[1]; - ((int16_t*)&y_128[1])[5] = -((int16_t*)&y_128[1])[5]; - y_128[2] = _mm_shufflelo_epi16(y_128[2],0x1e); - y_128[2] = _mm_shufflehi_epi16(y_128[2],0x1e); - ((int16_t*)&y_128[2])[1] = -((int16_t*)&y_128[2])[1]; - ((int16_t*)&y_128[2])[5] = -((int16_t*)&y_128[2])[5]; - y_128[3] = _mm_shufflelo_epi16(y_128[3],0x1e); - y_128[3] = _mm_shufflehi_epi16(y_128[3],0x1e); - ((int16_t*)&y_128[3])[1] = -((int16_t*)&y_128[3])[1]; - ((int16_t*)&y_128[3])[5] = -((int16_t*)&y_128[3])[5]; - } - - - x_128+=4; - y_128 +=4; - } - - - _mm_empty(); - _m_empty(); - - return(0); -} - -int rotate_cpx_vector2(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift, - uint8_t format) -{ - // Multiply elementwise two complex vectors of N elements - // x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // We assume x1 with a dynamic of 15 bit maximum - // - // alpha - input 2 in the format |Re0 Im0| - // We assume x2 with a dynamic of 15 bit maximum - // - // y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0) - // WARNING: log2_amp>0 can cause overflow!! - - uint32_t i; // loop counter - - register __m128i m0,m1; - - - __m128i *x_128; - __m128i *y_128; - - - shift = _mm_cvtsi32_si128(output_shift); - x_128 = (__m128i *)&x[0]; - - if (format==0) { // alpha is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; - } else { // input is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; - } - - y_128 = (__m128i *)&y[0]; - - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>1); i++) { - - - m0 = _mm_madd_epi16(x_128[i],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1=m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[i] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e - - y_128[i] = _mm_shufflelo_epi16(y_128[i],0x1e); - y_128[i] = _mm_shufflehi_epi16(y_128[i],0x1e); - ((int16_t*)&y_128[i])[1] = -((int16_t*)&y_128[i])[1]; - ((int16_t*)&y_128[i])[5] = -((int16_t*)&y_128[i])[5]; - } - } - - - _mm_empty(); - _m_empty(); - - - return(0); -} -*/ - -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, +#ifdef __AVX2__ +void rotate_cpx_vector(c16_t *x, + c16_t *alpha, + c16_t *y, uint32_t N, uint16_t output_shift) { @@ -372,28 +175,28 @@ int rotate_cpx_vector(int16_t *x, __m128i shift = _mm_cvtsi32_si128(output_shift); register simd_q15_t m0,m1,m2,m3; - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; + ((int16_t *)&alpha_128)[0] = alpha->r; + ((int16_t *)&alpha_128)[1] = -alpha->i; + ((int16_t *)&alpha_128)[2] = alpha->i; + ((int16_t *)&alpha_128)[3] = alpha->r; + ((int16_t *)&alpha_128)[4] = alpha->r; + ((int16_t *)&alpha_128)[5] = -alpha->i; + ((int16_t *)&alpha_128)[6] = alpha->i; + ((int16_t *)&alpha_128)[7] = alpha->r; #elif defined(__arm__) int32x4_t shift; int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,re32,im32; int16_t reflip[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; int32x4x2_t xtmp; - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; + ((int16_t *)&alpha_128)[0] = alpha->r; + ((int16_t *)&alpha_128)[1] = alpha->i; + ((int16_t *)&alpha_128)[2] = alpha->r; + ((int16_t *)&alpha_128)[3] = alpha->i; + ((int16_t *)&alpha_128)[4] = alpha->r; + ((int16_t *)&alpha_128)[5] = alpha->i; + ((int16_t *)&alpha_128)[6] = alpha->r; + ((int16_t *)&alpha_128)[7] = alpha->i; int16x8_t bflip = vrev32q_s16(alpha_128); int16x8_t bconj = vmulq_s16(alpha_128,*(int16x8_t *)reflip); shift = vdupq_n_s32(-output_shift); @@ -439,9 +242,9 @@ int rotate_cpx_vector(int16_t *x, _mm_empty(); _m_empty(); - return(0); + return; } - +#endif /* int mult_vector32_scalar(int16_t *x1, int x2, @@ -536,7 +339,7 @@ main () int16_t input[256] __attribute__((aligned(16))); int16_t input2[256] __attribute__((aligned(16))); int16_t output[256] __attribute__((aligned(16))); - int16_t alpha[2]; + c16_t alpha; int i; @@ -574,8 +377,8 @@ main () input2[14] = 1000; input2[15] = 2000; - alpha[0]=32767; - alpha[1]=0; + alpha->r=32767; + alpha->i=0; //mult_cpx_vector(input,input2,output,L,0); rotate_cpx_vector_norep(input,alpha,input,L,15); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 723813fbb6..d4b28361d2 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -60,7 +60,7 @@ typedef struct OAIgraph { int h; int waterFallh; double *waterFallAvg; - boolean_t initDone; + bool initDone; int iteration; void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id); void (*nrUEfunct)(scopeGraphData_t **data, struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id); @@ -208,7 +208,7 @@ static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len *y=old_y; } -static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, bool NoAutoScale) { fl_redraw_object(graph->graph); if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 839beb3dc9..c471978f46 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -37,6 +37,7 @@ extern "C" { #include #include #include "PHY/sse_intrin.h" +#include "common/utils/assertions.h" #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) @@ -104,15 +105,6 @@ void multadd_complex_vector_real_scalar(int16_t *x, uint8_t zero_flag, uint32_t N); -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift); - - - - /*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev) \brief Initialize the FFT engine for a given size @param size Size of the FFT @@ -461,7 +453,7 @@ idft_size_idx_t get_idft(int ofdm_symbol_size) } -/*!\fn int32_t rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift) +/*!\fn int32_t rotate_cpx_vector(c16_t *x,c16_t *alpha,c16_t *y,uint32_t N,uint16_t output_shift) This function performs componentwise multiplication of a vector with a complex scalar. @param x Vector input (Q1.15) in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)| @param alpha Scalar input (Q1.15) in the format |Re0 Im0| @@ -471,11 +463,11 @@ This function performs componentwise multiplication of a vector with a complex s The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$ */ -int32_t rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift); +void rotate_cpx_vector(c16_t *x, + c16_t *alpha, + c16_t *y, + uint32_t N, + uint16_t output_shift); //cadd_sv.c diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index d13fe260de..c93e3a7de9 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -754,7 +754,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// harq_pid @@ -775,7 +775,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// Format @@ -806,7 +806,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// Format @@ -907,7 +907,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela -#define MCS_COUNT 28 +#define MCS_COUNT 29 #define MCS_TABLE_LENGTH_MAX 64 diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 51601d5f05..b8a1e09e1d 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -188,8 +188,6 @@ typedef struct { uint8_t codebook_index; /// Maximum number of HARQ processes uint8_t Mdlharq; - /// Maximum number of HARQ rounds - uint8_t Mlimit; /// MIMO transmission mode indicator for this sub-frame uint8_t Kmimo; /// Nsoft parameter related to UE Category @@ -345,8 +343,6 @@ typedef struct { typedef struct { /// Pointers to 16 HARQ processes for the ULSCH NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; - /// Current HARQ process id - int harq_process_id[NR_MAX_SLOTS_PER_FRAME]; /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// ACK/NAK Bundling flag @@ -373,8 +369,6 @@ typedef struct { uint8_t cyclicShift; /// for cooperative communication uint8_t cooperation_flag; - /// Maximum number of HARQ rounds - uint8_t Mlimit; /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last LDPC decoding @@ -765,8 +759,8 @@ typedef struct PHY_VARS_gNB_s { /// SRS variables nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX]; - /// CSI-RS variables - nr_csi_rs_info_t *nr_csi_rs_info; + /// CSI variables + nr_csi_info_t *nr_csi_info; uint8_t pbch_configured; char gNB_generate_rar; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index bd6808c54d..9896af13fc 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -878,8 +878,8 @@ typedef struct { /// SRS variables nr_srs_info_t *nr_srs_info; - /// CSI-RS variables - nr_csi_rs_info_t *nr_csi_rs_info; + /// CSI variables + nr_csi_info_t *nr_csi_info; //#if defined(UPGRADE_RAT_NR) #if 1 @@ -978,8 +978,8 @@ typedef struct { SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; #endif - - int dl_stats[5]; + int dl_errors; + int dl_stats[8]; void* scopeData; } PHY_VARS_NR_UE; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 9c8e90a9c7..33451944ef 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -43,6 +43,7 @@ #define nr_slot_t lte_subframe_t #define MAX_NUM_SUBCARRIER_SPACING 5 +#define NR_MAX_OFDM_SYMBOL_SIZE 4096 #define NR_NB_SC_PER_RB 12 #define NR_NB_REG_PER_CCE 6 @@ -241,35 +242,19 @@ typedef struct { typedef struct { uint16_t sc_list_length; - uint16_t *sc_list; + uint16_t sc_list[6*273]; uint8_t srs_generated_signal_bits; - int32_t *srs_generated_signal; - int32_t **srs_received_signal; - int32_t **srs_ls_estimated_channel; - int32_t **srs_estimated_channel_freq; - int32_t **srs_estimated_channel_time; - int32_t **srs_estimated_channel_time_shifted; - uint32_t *noise_power; + int32_t srs_generated_signal[OFDM_SYMBOL_SIZE_SAMPLES_MAX * MAX_NUM_NR_SRS_SYMBOLS]; } nr_srs_info_t; typedef struct { - uint8_t N_cdm_groups; - uint8_t CDM_group_size; - uint8_t kprime; - uint8_t lprime; - uint8_t N_ports; - uint8_t j[16]; - uint8_t koverline[16]; - uint8_t loverline[16]; uint16_t csi_gold_init; uint32_t ***nr_gold_csi_rs; uint8_t csi_rs_generated_signal_bits; int32_t **csi_rs_generated_signal; - int32_t **csi_rs_received_signal; - int32_t ***csi_rs_ls_estimated_channel; - int32_t ***csi_rs_estimated_channel_freq; - uint32_t *noise_power; -} nr_csi_rs_info_t; + bool csi_im_meas_computed; + uint32_t interference_plus_noise_power; +} nr_csi_info_t; typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; @@ -359,10 +344,10 @@ struct NR_DL_FRAME_PARMS { lte_prefix_type_t Ncp; /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 /// First dimension is for the direction of the link (0 DL, 1 UL) - int16_t symbol_rotation[2][224*2]; + c16_t symbol_rotation[2][224]; /// sequence used to compensate the phase rotation due to timeshifted OFDM symbols /// First dimenstion is for different CP lengths - int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); + c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); /// shift of pilot position in one RB uint8_t nushift; /// SRS configuration from TS 38.331 RRC diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index dc84279a96..443b1c7989 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -71,9 +71,9 @@ #include "common/utils/system.h" #include - -extern int oai_exit; - +#include "openair1/SCHED/sched_common_extern.h" +#include "targets/RT/USER/lte-softmodem.h" +#include "common/ran_context.h" void feptx0(RU_t *ru, int slot) @@ -616,9 +616,11 @@ void init_fep_thread(RU_t *ru, } -extern void kill_fep_thread(RU_t *ru) +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); @@ -630,9 +632,11 @@ extern void kill_fep_thread(RU_t *ru) } -extern void kill_feptx_thread(RU_t *ru) +void kill_feptx_thread(RU_t *ru) { RU_proc_t *proc = &ru->proc; + if (proc->pthread_feptx == 0) + return; pthread_mutex_lock( &proc->mutex_feptx ); proc->instance_cnt_feptx = 0; pthread_cond_signal(&proc->cond_feptx); diff --git a/openair1/SCHED/sched_common_extern.h b/openair1/SCHED/sched_common_extern.h index b5edc6f38e..2236c5f31d 100644 --- a/openair1/SCHED/sched_common_extern.h +++ b/openair1/SCHED/sched_common_extern.h @@ -29,4 +29,6 @@ extern int16_t hundred_times_delta_TF[100]; extern uint16_t hundred_times_log10_NPRB[100]; +void kill_fep_thread(RU_t *ru); + #endif /*__SCHED_EXTERN_H__ */ diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 48728ba44a..5c08a0f479 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -251,7 +251,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ if (number_dl_pdu>0) oai_nfapi_dl_tti_req(DL_req); - } stop_meas(&gNB->schedule_response_stats); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 84ba6b6bcd..e079caa9e5 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -45,24 +45,12 @@ #include "intertask_interface.h" //#define DEBUG_RXDATA +//#define SRS_IND_DEBUG uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,254,32,34,36,38,40,42,44,46,254,254,48,50,52,54,56,58,60,62}; extern uint8_t nfapi_mode; -void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp) { - - uint8_t sco = 0; - if (((fp->freq_range == nr_FR1) && (cfg->ssb_table.ssb_subcarrier_offset.value<24)) || - ((fp->freq_range == nr_FR2) && (cfg->ssb_table.ssb_subcarrier_offset.value<12)) ) { - if (fp->freq_range == nr_FR1) - sco = cfg->ssb_table.ssb_subcarrier_offset.value>>cfg->ssb_config.scs_common.value; - } - - fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + sco); - LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); -} - void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; @@ -84,7 +72,12 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_ int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot - nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier + // setting the first subcarrier + const int scs = cfg->ssb_config.scs_common.value; + const int prb_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>scs : ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>(scs-2); + const int sc_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset>>scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset; + fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier, prb_offset, sc_offset); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); nr_generate_pss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); @@ -179,7 +172,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, if (csirs->active == 1) { LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; - nr_generate_csi_rs(gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot); + nr_generate_csi_rs(&gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_info, csi_params, slot, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); csirs->active = 0; } } @@ -200,14 +193,12 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { NR_gNB_ULSCH_t *ulsch = rdata->ulsch; int r = rdata->segment_r; nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id]->harq_processes[rdata->harq_pid]->ulsch_pdu; - bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter); ulsch_harq->processedSegments++; LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n", rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments); gNB->nbDecode--; LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode); - if (decodeSuccess) { memcpy(ulsch_harq->b+rdata->offset, ulsch_harq->c[r], @@ -229,7 +220,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { //int dumpsig=0; // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { - if (decodeSuccess) { + if (decodeSuccess && !gNB->pusch_vars[rdata->ulsch_id]->DTX) { LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); ulsch_harq->status = SCH_IDLE; @@ -249,13 +240,6 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { ulsch_harq->ulsch_pdu.rb_size, ulsch_harq->TBS, r); - ulsch_harq->round++; - if (ulsch_harq->round >= ulsch->Mlimit) { - ulsch_harq->status = SCH_IDLE; - ulsch_harq->round = 0; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - } ulsch_harq->handled = 1; LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); @@ -421,17 +405,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, if (timing_advance_update > 63) timing_advance_update = 63; if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update); - else if (harq_process->round>0 || dtx_flag == 0) { // increment round if crc_flag == 1 and not(dtx_flag ==1 and round==0) - harq_process->round++; - if (harq_process->round >= ulsch->Mlimit) { - harq_process->status = SCH_IDLE; - harq_process->round = 0; - harq_process->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); - } - } - // estimate UL_CQI for MAC + // estimate UL_CQI for MAC int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot); @@ -582,7 +557,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(PHY,"symbol %d Filling rb_mask_ul rb_size %d\n",symbol,ulsch_harq->ulsch_pdu.rb_size); for (rb=0; rbulsch_pdu.rb_size; rb++) { rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start; - gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31)); + gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31); } } } @@ -634,10 +609,38 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } +int fill_srs_reported_symbol_list(nfapi_nr_srs_indication_reported_symbol_t *reported_symbol_list, + const nfapi_nr_srs_pdu_t *srs_pdu, + const int N_RB_UL, + const int8_t *snr_per_rb, + const int srs_est) { + + reported_symbol_list->num_rbs = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + + if (!reported_symbol_list->rb_list) { + reported_symbol_list->rb_list = (nfapi_nr_srs_indication_reported_symbol_resource_block_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_indication_reported_symbol_resource_block_t)); + } + + for(int rb = 0; rb < reported_symbol_list->num_rbs; rb++) { + if (srs_est<0) { + reported_symbol_list->rb_list[rb].rb_snr = 0xFF; + } else if (snr_per_rb[rb] < -64) { + reported_symbol_list->rb_list[rb].rb_snr = 0; + } else if (snr_per_rb[rb] > 63) { + reported_symbol_list->rb_list[rb].rb_snr = 0xFE; + } else { + reported_symbol_list->rb_list[rb].rb_snr = (snr_per_rb[rb] + 64)<<1; + } + } + + return 0; +} + int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ int pucch_decode_done = 0; int pusch_decode_done = 0; + int pusch_DTX = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); @@ -708,6 +711,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(PHY,"%d.%d Calling nr_decode_pucch2\n",frame_rx,slot_rx); nr_decode_pucch2(gNB, + frame_rx, slot_rx, uci_pdu_format2, pucch_pdu); @@ -724,14 +728,12 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { for (int ULSCH_id=0;ULSCH_idnumber_of_nr_ulsch_max;ULSCH_id++) { NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id]; - int harq_pid; - int no_sig; NR_UL_gNB_HARQ_t *ulsch_harq; if ((ulsch) && (ulsch->rnti > 0)) { // for for an active HARQ process - for (harq_pid=0;harq_pidharq_processes[harq_pid]; AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid); if ((ulsch_harq->status == NR_ACTIVE) && @@ -772,16 +774,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { pusch_decode_done = 1; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); - start_meas(&gNB->rx_pusch_stats); - no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); - stop_meas(&gNB->rx_pusch_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0); - - if (no_sig) { - LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); - nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); - return 1; - } + start_meas(&gNB->rx_pusch_stats); + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); gNB->pusch_vars[ULSCH_id]->ulsch_power_tot=0; gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot=0; for (int aarx=0;aarxframe_parms.nb_antennas_rx;aarx++) { @@ -804,7 +798,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { /* in case of phy_test mode, we still want to decode to measure execution time. Therefore, we don't yet call nr_fill_indication, it will be called later */ nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); - return 1; + pusch_DTX++; + continue; } } else { LOG_D(PHY, "PUSCH detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, @@ -833,29 +828,88 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i); + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; + uint8_t N_symb_SRS = 1<num_symbols; + int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; + int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; + int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + uint32_t noise_power_per_rb[srs_pdu->bwp_size]; + int8_t snr_per_rb[srs_pdu->bwp_size]; + uint32_t signal_power; + uint32_t noise_power; + int8_t snr; // At least currently, the configuration is constant, so it is enough to generate the sequence just once. if(gNB->nr_srs_info[i]->sc_list_length == 0) { - generate_srs_nr(srs_pdu, &gNB->frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); + generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); } - nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info[i], gNB->nr_srs_info[i]->srs_received_signal); + const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); - nr_srs_channel_estimation(gNB,frame_rx,slot_rx,srs_pdu, - gNB->nr_srs_info[i], - gNB->nr_srs_info[i]->srs_generated_signal, - gNB->nr_srs_info[i]->srs_received_signal, - gNB->nr_srs_info[i]->srs_estimated_channel_freq, - gNB->nr_srs_info[i]->srs_estimated_channel_time, - gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted, - gNB->nr_srs_info[i]->noise_power); + if (srs_est >= 0) { + nr_srs_channel_estimation(gNB, + frame_rx, + slot_rx, + srs_pdu, + gNB->nr_srs_info[i], + gNB->nr_srs_info[i]->srs_generated_signal, + srs_received_signal, + srs_ls_estimated_channel, + srs_estimated_channel_freq, + srs_estimated_channel_time, + srs_estimated_channel_time_shifted, + &signal_power, + noise_power_per_rb, + &noise_power, + snr_per_rb, + &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(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_freq[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(gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_time_shifted[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) : 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)); + } + 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); + + gNB->UL_INFO.srs_ind.number_of_pdus += 1; + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = 0x%04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_symbols); + 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); + } +#endif srs->active = 0; } @@ -869,5 +923,5 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); - return 0; + return pusch_DTX; } diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 7672aee8a2..fa354d2284 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -405,7 +405,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void * typeSpecific); + void *typeSpecific); bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 046f67a7d0..f4c863bb40 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -393,7 +393,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ case FAPI_NR_DL_CONFIG_TYPE_CSI_IM: csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15; memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t)); - csirs_vars->active = true; + csiim_vars->active = true; break; case FAPI_NR_DL_CONFIG_TYPE_CSI_RS: csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15; diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index a9ff01d78a..dc62ea646c 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -308,7 +308,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) dl_harq->status = SCH_IDLE; dl_harq->first_rx = 1; dl_harq->DLround = 0; - dl_harq->DCINdi = 1; + dl_harq->Ndi = 2; // set to an invalid value dl_harq->ack = DL_ACKNACK_NO_SET; } @@ -329,7 +329,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) * *********************************************************************/ -void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int rv, uint8_t rnti_type) { +void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dci_ndi, int rv, uint8_t rnti_type) { if (rnti_type == _SI_RNTI_ || rnti_type == _P_RNTI_ || @@ -339,10 +339,9 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int dl_harq->first_rx = 1; } else { LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n", - dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no"); + dl_harq, harq_pid, rv, dci_ndi, rnti_type, dl_harq->Ndi != dci_ndi ? "yes":"no"); AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv); - - if (ndi!=dl_harq->DCINdi) { + if (dci_ndi!=dl_harq->Ndi) { if (dl_harq->ack == DL_NACK) LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid); else @@ -354,7 +353,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv); } - if (ndi!=dl_harq->DCINdi) { + if (dci_ndi!=dl_harq->Ndi) { dl_harq->first_rx = true; dl_harq->DLround = 0; } else { @@ -364,7 +363,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int dl_harq->status = ACTIVE; - dl_harq->DCINdi = ndi; + dl_harq->Ndi = dci_ndi; //dl_harq->status = SCH_IDLE; } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index d366ae9ec1..09c24d676d 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -121,9 +121,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, - UE_nr_rxtx_proc_t *proc, - void * typeSpecific){ - + UE_nr_rxtx_proc_t *proc, + void *typeSpecific){ NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -176,6 +175,11 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id]; break; + case FAPI_NR_CSIRS_IND: + memcpy(&rx_ind->rx_indication_body[n_pdus - 1].csirs_measurements, + (fapi_nr_csirs_measurements_t*)typeSpecific, + sizeof(*(fapi_nr_csirs_measurements_t*)typeSpecific)); + break; default: break; } @@ -1321,8 +1325,7 @@ int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_ //uint8_t half_frame_index = fp->half_frame_bit; //uint8_t i_ssb = fp->ssb_index; uint8_t Lmax = fp->Lmax; - - if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){ + if ((config->ssb_table.ssb_period > 0) && !(frame % (1 << (config->ssb_table.ssb_period - 1)))) { if(Lmax <= 8) { if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000)) @@ -1477,7 +1480,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { LOG_I(NR_PHY,"============================================\n"); - LOG_I(NR_PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]); + // fixed text + 8 HARQs rounds à 10 ("999999999/") + NULL + // if we use 999999999 HARQs, that should be sufficient for at least 138 hours + const size_t harq_output_len = 31 + 10 * 8 + 1; + char output[harq_output_len]; + char *p = output; + const char *end = output + harq_output_len; + p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]); + for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round) + p += snprintf(p, end - p,"/%d", ue->dl_stats[round]); + LOG_I(NR_PHY,"%s/0\n", output); + LOG_I(NR_PHY,"============================================\n"); } @@ -1692,6 +1705,19 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // do procedures for CSI-IM if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) { + int l_csiim[4] = {-1, -1, -1, -1}; + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + bool nr_slot_fep_done = false; + for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { + if (l_csiim[symb_idx2] == ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]) { + nr_slot_fep_done = true; + } + } + l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; + if(nr_slot_fep_done == false) { + nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx); + } + } nr_ue_csi_im_procedures(ue, proc, gNB_id); ue->csiim_vars[gNB_id]->active = 0; } diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index aa0ff0db80..cdf4cf39f9 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -460,7 +460,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue, is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; // check ACK/SR transmission - if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE) { + if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == false) { if(is_SR_TXOp(ue,proc,eNB_id)) { uint32_t SR_payload = 0; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 231d63cf04..8aff47c86b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -512,12 +512,16 @@ int main(int argc, char **argv) { int re; int s,Kr,Kr_bytes; LTE_DL_FRAME_PARMS *frame_parms; - double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; - double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2]; - double *s_re[2]= {s_re0,s_re1}; - double *s_im[2]= {s_im0,s_im1}; - double *r_re[2]= {r_re0,r_re1}; - double *r_im[2]= {r_im0,r_im1}; + double *tmpTX[4], *tmpRX[4] ; + for (int i = 0; i < 4; i++) { + tmpTX[i] = malloc(30720 * NB_ANTENNAS_TX * sizeof(*tmpTX)); + tmpRX[i] = malloc(30720 * NB_ANTENNAS_RX * sizeof(*tmpRX)); + } + double *s_re[NB_ANTENNAS_TX] = {tmpTX[0], tmpTX[1]}; + double *s_im[NB_ANTENNAS_TX] = {tmpTX[2], tmpTX[3]}; + double *r_re[NB_ANTENNAS_RX] = {tmpRX[0], tmpRX[1]}; + double *r_im[NB_ANTENNAS_RX] = {tmpRX[2], tmpRX[3]}; + uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; int eNB_id = 0; unsigned char round; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 0843d00ffd..0f98eb337a 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -358,7 +358,7 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0}; + unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0}; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; @@ -387,7 +387,6 @@ int main(int argc, char **argv) { double cpu_freq_GHz; int iter_trials; uint32_t UL_alloc_pdu; - int s,Kr,Kr_bytes; int dump_perf=0; static int dump_table =0; double effective_rate=0.0; @@ -1233,20 +1232,21 @@ int main(int argc, char **argv) { if (n_frames==1) { printf("ULSCH errors found o_ACK[0]= %d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0]); - +#ifdef DUMP_EACH_VALUE + int Kr_bytes; for (s=0; sulsch[0]->harq_processes[harq_pid]->C; s++) { if (sulsch[0]->harq_processes[harq_pid]->Cminus) - Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus; + Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus; else - Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; - - Kr_bytes = Kr>>3; + Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; + Kr_bytes = Kr_bytes >> 3; printf("Decoded_output (Segment %d):\n",s); for (i=0; iulsch[0]->harq_processes[harq_pid]->c[s][i], eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]); } +#endif dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); round=5; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index d3da01638a..5141fc2c79 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -115,16 +115,16 @@ int main(int argc, char **argv) //int run_initial_sync=0; int loglvl = OAILOG_WARNING; uint8_t dlsch_threads = 0; - float target_error_rate = 0.01; - uint64_t SSB_positions=0x01; - uint16_t nb_symb_sch = 12; - uint16_t nb_rb = 50; - uint8_t Imcs = 9; - uint8_t mcs_table = 0; - double DS_TDL = .03; - cpuf = get_cpu_freq_GHz(); - char gNBthreads[128]="n"; - int Tbslbrm = 950984; + float target_error_rate = 0.01; + uint64_t SSB_positions=0x01; + uint16_t nb_symb_sch = 12; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; + uint8_t mcs_table = 0; + double DS_TDL = .03; + cpuf = get_cpu_freq_GHz(); + char gNBthreads[128]="n"; + int Tbslbrm = 950984; if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n"); @@ -300,7 +300,7 @@ int main(int argc, char **argv) break; case 'X': - strncpy(gNBthreads, optarg, sizeof(gNBthreads)); + strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1); gNBthreads[sizeof(gNBthreads)-1]=0; break; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1a526174f0..3ff3fe66cd 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -100,9 +100,17 @@ nfapi_ue_release_request_body_t release_rntis; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { -return 0; +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { + return 0; } int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) { @@ -210,7 +218,6 @@ int nr_derive_key(int alg_type, uint8_t alg_id, } void config_common(int Mod_idP, - int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc); @@ -242,10 +249,10 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, return 0; } -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - void processSlotTX(void *arg) {} +nr_bler_struct nr_bler_data[NR_NUM_MCS]; + //nFAPI P7 dummy functions to avoid linking errors int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } @@ -273,10 +280,9 @@ void nr_dlsim_preprocessor(module_id_t module_id, NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0]; AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP; NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - sched_ctrl->search_space = get_searchspace(NULL, scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss); uint8_t nr_of_candidates = 0; if (g_mcsIndex < 4) { find_aggregation_candidates(&sched_ctrl->aggregation_level, @@ -288,7 +294,6 @@ void nr_dlsim_preprocessor(module_id_t module_id, &nr_of_candidates, sched_ctrl->search_space,4); } - sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss); uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti); int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], /* CC_id = */ 0, @@ -302,11 +307,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - nr_set_pdsch_semi_static(NULL, + nr_set_pdsch_semi_static(current_BWP, scc, - UE_info->CellGroup, - sched_ctrl->active_bwp, - NULL, /* tda = */ 0, g_nrOfLayers, sched_ctrl, @@ -318,10 +320,10 @@ void nr_dlsim_preprocessor(module_id_t module_id, sched_pdsch->mcs = g_mcsIndex; /* the following might override the table that is mandated by RRC * configuration */ - ps->mcsTableIdx = g_mcsTableIdx; + current_BWP->mcsTableIdx = g_mcsTableIdx; - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + 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, @@ -349,7 +351,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart); AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize); AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs); - AssertFatal(ps->mcsTableIdx >= 0 && ps->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", ps->mcsTableIdx); + AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx); } typedef struct { @@ -671,7 +673,7 @@ int main(int argc, char **argv) break; case 'X': - strncpy(gNBthreads, optarg, sizeof(gNBthreads)); + strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1); gNBthreads[sizeof(gNBthreads)-1]=0; break; @@ -757,11 +759,13 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) RC.nb_nr_mac_CC[i] = 1; - mac_top_init_gNB(); + mac_top_init_gNB(ngran_gNB); gNB_mac = RC.nrmac[0]; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); + gNB_mac->dl_bler.harq_round_max = num_rounds; + /* // read in SCGroupConfig AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); @@ -857,9 +861,9 @@ int main(int argc, char **argv) gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 0, 0, NULL); + rrc_mac_config_req_gNB(0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); // reset preprocessor to the one of DLSIM after it has been set during // rrc_mac_config_req_gNB gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; @@ -867,6 +871,8 @@ int main(int argc, char **argv) N_RB_DL = gNB->frame_parms.N_RB_DL; NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0]; + configure_UE_BWP(RC.nrmac[0], scc, &UE_info->UE_sched_ctrl, NULL, UE_info); + // stub to configure frame_parms // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); // call MAC to configure common parameters @@ -878,55 +884,22 @@ int main(int argc, char **argv) if (g_rbStart < 0) g_rbStart=0; if (g_rbSize < 0) g_rbSize = N_RB_DL - g_rbStart; - double fs,bw; + double fs,txbw,rxbw; + uint32_t samples; - if (mu == 0 && N_RB_DL == 25) { - fs = 7.68e6; - bw = 5e6; - } - else if (mu == 1 && N_RB_DL == 217) { - fs = 122.88e6; - bw = 80e6; - } - else if (mu == 1 && N_RB_DL == 245) { - fs = 122.88e6; - bw = 90e6; - } - else if (mu == 1 && N_RB_DL == 273) { - fs = 122.88e6; - bw = 100e6; - } - else if (mu == 1 && N_RB_DL == 106) { - fs = 61.44e6; - bw = 40e6; - } - else if (mu == 1 && N_RB_DL == 133) { - fs = 61.44e6; - bw = 50e6; - } - else if (mu == 1 && N_RB_DL == 162) { - fs = 61.44e6; - bw = 60e6; - } - else if (mu == 1 && N_RB_DL == 24) { - fs = 15.36e6; - bw = 10e6; - } - else if (mu == 3 && N_RB_DL == 66) { - fs = 122.88e6; - bw = 100e6; - } - else if (mu == 3 && N_RB_DL == 32) { - fs = 61.44e6; - bw = 50e6; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + get_samplerate_and_bw(mu, + N_RB_DL, + frame_parms->threequarter_fs, + &fs, + &samples, + &txbw, + &rxbw); gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs/1e6,//sampling frequency in MHz - bw, + txbw, 30e-9, 0, 0, @@ -1143,7 +1116,7 @@ int main(int argc, char **argv) Sched_INFO.frame = frame; Sched_INFO.slot = slot; Sched_INFO.DL_req = &gNB_mac->DL_req[0]; - Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot]; + Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[0]; Sched_INFO.UL_dci_req = NULL; Sched_INFO.TX_req = &gNB_mac->TX_req[0]; pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 21802cd41a..75e3d998ff 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -40,4 +40,4 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void * typeSpecific ) {} + void *typeSpecific ) {} diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ca696d4f9c..0e648c945f 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -67,7 +67,10 @@ openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; uint64_t get_softmodem_optmask(void) {return 0;} -softmodem_params_t *get_softmodem_params(void) {return 0;} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) { + return &softmodem_params; +} void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} @@ -171,8 +174,10 @@ int main(int argc, char **argv) uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; uint64_t SSB_positions=0x01; + int ssb_subcarrier_offset = 0; channel_desc_t *gNB2UE; + get_softmodem_params()->sa = 1; //uint8_t extended_prefix_flag=0; //int8_t interf1=-21,interf2=-21; @@ -214,7 +219,7 @@ int main(int argc, char **argv) exit_fun("[NR_PBCHSIM] Error, configuration module init failed\n"); } - while ((c = getopt (argc, argv, "F:g:hIL:m:M:n:N:o:P:r:R:s:S:x:y:z:")) != -1) { + while ((c = getopt (argc, argv, "F:g:hIL:m:M:n:N:o:O:P:r:R:s:S:x:y:z:")) != -1) { switch (c) { /*case 'f': write_output_file=1; @@ -312,6 +317,10 @@ int main(int argc, char **argv) Nid_cell = atoi(optarg); break; + case 'O': + ssb_subcarrier_offset = atoi(optarg); + break; + case 'o': cfo = atof(optarg); #ifdef DEBUG_NR_PBCHSIM @@ -414,6 +423,7 @@ int main(int argc, char **argv) printf("-n Number of frames to simulate\n"); printf("-N Nid_cell\n"); printf("-o Carrier frequency offset in Hz\n"); + printf("-O SSB subcarrier offset\n"); //printf("-O oversampling factor (1,2,4,8,16)\n"); //printf("-p Use extended prefix mode\n"); printf("-P PBCH phase, allowed values 0-3\n"); @@ -454,10 +464,11 @@ int main(int argc, char **argv) frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%4; frame_parms->ssb_type = nr_ssb_type_C; + frame_parms->freq_range = mu<2 ? nr_FR1 : nr_FR2; nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,1); - nr_set_ssb_first_subcarrier(&gNB->gNB_config,frame_parms); + frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset; uint8_t n_hf = 0; int cyclic_prefix_type = NFAPI_CP_NORMAL; @@ -578,8 +589,12 @@ int main(int argc, char **argv) for (i=0; iLmax; i++) { if((SSB_positions >> i) & 0x01) { + const int sc_offset = frame_parms->freq_range == nr_FR1 ? ssb_subcarrier_offset<freq_range == nr_FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2); msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33; msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i; + msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset; + msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = prb_offset; start_symbol = nr_get_ssb_start_symbol(frame_parms,i); int slot = start_symbol/14; @@ -722,8 +737,8 @@ int main(int argc, char **argv) if (ret<0) n_errors++; } else { - UE_nr_rxtx_proc_t proc={0}; - NR_UE_PDCCH_CONFIG phy_pdcch_config={0}; + UE_nr_rxtx_proc_t proc={0}; + NR_UE_PDCCH_CONFIG phy_pdcch_config={0}; UE->rx_offset=0; uint8_t ssb_index = 0; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 33717c944d..76776ce110 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -92,9 +92,17 @@ int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { -return 0; +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { + return 0; } int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) { diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index fda7c0dcba..0b159e36e9 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -27,6 +27,7 @@ #include #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" +#include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" #include "common/ran_context.h" #include "PHY/types.h" @@ -391,45 +392,18 @@ int main(int argc, char **argv) nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); - double fs,bw,scs,eps; + double fs,txbw,rxbw; + uint32_t samples; - if (mu == 1 && N_RB_DL == 217) { - fs = 122.88e6; - bw = 80e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 245) { - fs = 122.88e6; - bw = 90e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 273) { - fs = 122.88e6; - bw = 100e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 106) { - fs = 61.44e6; - bw = 40e6; - scs = 30000; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + get_samplerate_and_bw(mu, + N_RB_DL, + frame_parms->threequarter_fs, + &fs, + &samples, + &txbw, + &rxbw); - // cfo with respect to sub-carrier spacing - eps = cfo/scs; - - // computation of integer and fractional FO to compare with estimation results - int IFO; - if(eps!=0.0){ - printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); - if (eps>0) - IFO=(int)(eps+0.5); - else - IFO=(int)(eps-0.5); - printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); - } - - UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0, 0); + UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, txbw, DS_TDL,0, 0, 0, 0); if (UE2gNB==NULL) { printf("Problem generating channel model. Exiting.\n"); @@ -478,9 +452,6 @@ int main(int argc, char **argv) memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); UE->frame_parms.nb_antennas_rx=1; - if(eps!=0.0) - UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation - if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation\n"); @@ -569,7 +540,7 @@ int main(int argc, char **argv) } random_channel(UE2gNB,0); - freq_channel(UE2gNB,N_RB_DL,2*N_RB_DL+1,scs/1000); + freq_channel(UE2gNB,N_RB_DL,2*N_RB_DL+1,15<frame_parms.ofdm_symbol_size; for (int re=0;re1) { @@ -705,7 +677,7 @@ int main(int argc, char **argv) pucch_pdu.second_hop_prb = N_RB_DL-1; } else pucch_pdu.freq_hop_flag = 0; - nr_decode_pucch2(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); + nr_decode_pucch2(gNB,nr_frame_tx,nr_slot_tx,&uci_pdu,&pucch_pdu); int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; for (int i=0;iif_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); + rrc_mac_config_req_gNB(0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, + rrc_mac_config_req_gNB(0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, secondaryCellGroup); frame_parms->nb_antennas_tx = 1; frame_parms->nb_antennas_rx = n_rx; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index 31fe15a6de..12d50065fa 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -165,7 +165,7 @@ void common_pucch_configuration(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int pucch_in int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - bool reset_harq = FALSE; + bool reset_harq = false; printf("%s", tst_separator); @@ -175,7 +175,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr common_pucch_configuration(ue, gNB_id, TST_PUCCH_COMMON_CONFIG_INDEX_KO); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -186,7 +186,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to acknownlegment not set \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -194,7 +194,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to DAI not set \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -202,7 +202,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = NR_DL_MAX_DAI + 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -210,7 +210,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = 0; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -218,7 +218,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->send_harq_status = 1; /* ack ready to be send */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -228,7 +228,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -236,7 +236,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to PUCCH format with multiple cells not already implemented \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -260,7 +260,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - bool reset_harq = FALSE; + bool reset_harq = false; printf("%s", tst_separator); @@ -273,7 +273,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in prach mode: one positive downlink ACKnowledgment \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -281,7 +281,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in prach mode: one negative downlink ACKnowledgment \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -304,7 +304,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: two positive downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -312,7 +312,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: one positive and one negative downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -320,22 +320,22 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: two negative downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } harq_status->ack = DL_ACK; - reset_harq = TRUE; + reset_harq = true; printf("\n => Test : PUCCH format from common config in dedicated mode: no resource is found \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } printf("\n => Test : PUCCH format from common config in dedicated mode: no PUCCH after reset of pending harq ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -362,7 +362,7 @@ void init_pucch_dedicated_configuration(PHY_VARS_NR_UE *ue, uint8_t gNB_id) int i,j; /* set cell group parameters which are supported */ - ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH = FALSE; + ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH = false; ue->cell_group_config.physicalCellGroupConfig.pdsch_HARQ_ACK_Codebook = dynamic; ue->PDSCH_ServingCellConfig.codeBlockGroupTransmission = NULL; @@ -554,7 +554,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, #define TST_NB_STEP_SINGLE_TRANSPORT_BLOCK (4) int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int dl_harq_pid[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH }; int pucch_resource_indicator[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK][2] = { { 0, 4 }, { 1, 0 } , { 1, 3 } , { 5, 7 } }; NR_UE_HARQ_STATUS_t *harq_status; @@ -575,7 +575,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, printf("\n => Test : PUCCH format from dedicated config : pucch resource indicator is invalid \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -595,14 +595,14 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, /* reset ack context on last test */ if ((i == (TST_NB_STEP_SINGLE_TRANSPORT_BLOCK-1)) && (j == 1)) { - reset_harq = TRUE; + reset_harq = true; } harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; printf("\n => Test : PUCCH format from dedicated config with 1 transport block : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[i][j]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } } @@ -627,11 +627,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, harq_status->pucch_resource_indicator = pucch_resource_indicator[i][0]; } - reset_harq = TRUE; + reset_harq = true; printf("\n => Test : PUCCH format from dedicated config with 1 transport block and missed PDSCH : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[3][0]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -659,7 +659,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE #define TST_NB_STEP_TWO_TRANSPORT_BLOCKS (4) int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int dl_harq_pid[TST_NB_STEP_TWO_TRANSPORT_BLOCKS] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH }; int pucch_resource_indicator[TST_NB_STEP_TWO_TRANSPORT_BLOCKS][2] = { { 0, 1 }, { 3, 7 } , { 2 , 4 } , { 4 , 6 } }; NR_UE_HARQ_STATUS_t *harq_status; @@ -694,7 +694,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE /* reset ack context on last test */ if ((i == (TST_NB_STEP_TWO_TRANSPORT_BLOCKS-1)) && (j == 1)) { - reset_harq = TRUE; + reset_harq = true; } harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; @@ -703,7 +703,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE printf("\n => Test : PUCCH format from dedicated config with 2 transport blocks : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[i][j]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -714,7 +714,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE /* some transport blocks have been missed and they need to be nack by UE in order to be retransmitted by the network */ /* here first and third block receptions have been missed */ - reset_harq = TRUE; + reset_harq = true; for (int i = 1; i < TST_NB_STEP_TWO_TRANSPORT_BLOCKS; i = i + 1) { @@ -743,7 +743,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE printf("\n => Test : PUCCH format from dedicated config with 2 transport blocks and 1 missed PDSCH : with %d downlink ACKnowledgments and pucch resource indicator %d \n", 4, pucch_resource_indicator[3][0]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -775,7 +775,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE } } - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -907,7 +907,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 0; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { printf("Test fail \n"); v_return = -1; } @@ -916,7 +916,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -929,7 +929,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -958,7 +958,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - int reset_harq = 0; + bool reset_harq = false; int sr_config_id = 0; int sr_resource_id = 0; int sr_offset = 0; @@ -988,7 +988,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 0; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -997,7 +997,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 1; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1006,7 +1006,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro harq_status->pucch_resource_indicator = pucch_resource_indicator[1]; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1027,7 +1027,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 1; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1035,9 +1035,9 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro printf("\n => Test : PUCCH format from dedicated config with a positive scheduling request and two positive acks \n"); harq_status->pucch_resource_indicator = pucch_resource_indicator[1]; - reset_harq = TRUE; + reset_harq = true; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1065,7 +1065,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int sr_config_id = 0; int sr_resource_id = 0; int sr_offset = 0; @@ -1079,7 +1079,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("\n => Test : PUCCH format from dedicated config with CSI alone \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1102,7 +1102,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) ue->pucch_config_dedicated_nr[gNB_id].formatConfig[2-1]->simultaneousHARQ_ACK_CSI = enable_feature; /* format 2 */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1115,9 +1115,9 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) tst_scheduling_request_payload = 0; /* set sr payload */ - reset_harq = TRUE; + reset_harq = true; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1126,7 +1126,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) harq_status->pucch_resource_indicator = pucch_resource_indicator[4]; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1135,7 +1135,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("\n => Test : PUCCH format from dedicated config with positive SR and CSI \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 82b1557a5b..0ba9e196b1 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -42,7 +42,6 @@ void randominit(unsigned seed_init) { int i; // this need to be integrated with the existing rng, like taus: navid - printf("Initializing random number generator, seed %x\n",seed_init); if (seed_init == 0) { srand((unsigned)time(NULL)); @@ -51,6 +50,7 @@ void randominit(unsigned seed_init) } else { seed = seed_init; } + printf("Initializing random number generator, seed %x\n",seed); if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */ diff --git a/openair2/COMMON/commonDef.h b/openair2/COMMON/commonDef.h index b37230cdd4..e18db881f0 100644 --- a/openair2/COMMON/commonDef.h +++ b/openair2/COMMON/commonDef.h @@ -43,27 +43,6 @@ Description Contains global common definitions #include #include -/* boolean_t is also defined in openair2/COMMON/platform_types.h - * let's protect potential redefinition - */ - -#ifndef _BOOLEAN_T_DEFINED_ -#define _BOOLEAN_T_DEFINED_ - -typedef signed char boolean_t; - -#if !defined(TRUE) -#define TRUE (boolean_t)0x01 -#endif - -#if !defined(FALSE) -#define FALSE (boolean_t)0x00 -#endif - -#define BOOL_NOT(b) (b^TRUE) - -#endif /* _BOOLEAN_T_DEFINED_ */ - #define NAS_UE_ID_FMT "0x%06x" /****************************************************************************/ diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 0e857f3a83..f28e0e5ddf 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -46,6 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 5e5b4c37d3..cbc4d1c6f2 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -23,6 +23,7 @@ #define F1AP_MESSAGES_TYPES_H_ #include "rlc.h" +#include "s1ap_messages_types.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -39,15 +40,15 @@ #define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message #define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message #define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req -#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp +#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp #define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp +#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail #define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req #define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req -#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req /* Length of the transport layer address string * 160 bits / 8 bits by char. @@ -61,7 +62,6 @@ #define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32 #define F1AP_MAX_NO_UE_ID 1024 -#define F1AP_MAX_DU2CU_RRC_LENGTH 1024 typedef struct f1ap_net_ip_address_s { unsigned ipv4:1; @@ -309,7 +309,7 @@ typedef struct f1ap_initial_ul_rrc_message_s { uint16_t crnti; uint8_t *rrc_container; int rrc_container_length; - char du2cu_rrc_container[F1AP_MAX_DU2CU_RRC_LENGTH]; + uint8_t *du2cu_rrc_container; int du2cu_rrc_container_length; } f1ap_initial_ul_rrc_message_t; @@ -345,6 +345,35 @@ typedef struct f1ap_rb_failed_to_be_setup_s { long rb_id; } f1ap_rb_failed_to_be_setup_t; +typedef struct cu_to_du_rrc_information_s { + uint8_t * cG_ConfigInfo; + uint32_t cG_ConfigInfo_length; + uint8_t * uE_CapabilityRAT_ContainerList; + uint32_t uE_CapabilityRAT_ContainerList_length; + uint8_t * measConfig; + uint32_t measConfig_length; +}cu_to_du_rrc_information_t; + +typedef struct du_to_du_rrc_information_s { + uint8_t * cellGroupConfig; + uint8_t cellGroupConfig_length; + uint8_t * measGapConfig; + uint8_t measGapConfig_length; + uint8_t * requestedP_MaxFR1; + uint8_t requestedP_MaxFR1_length; +}du_to_cu_rrc_information_t; + +typedef enum QoS_information_e { + NG_RAN_QoS = 0, + EUTRAN_QoS = 1, +} QoS_information_t; + +typedef enum ReconfigurationCompl_e { + RRCreconf_info_not_present = 0, + RRCreconf_failure = 1, + RRCreconf_success = 2, +} ReconfigurationCompl_t; + typedef struct f1ap_ue_context_setup_s { uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti uint32_t gNB_DU_ue_id; @@ -357,40 +386,27 @@ typedef struct f1ap_ue_context_setup_s { uint8_t servCellIndex; uint8_t *cellULConfigured; uint32_t servCellId; - uint8_t *cu_to_du_rrc_information; + cu_to_du_rrc_information_t *cu_to_du_rrc_information; uint8_t cu_to_du_rrc_information_length; - uint8_t *du_to_cu_rrc_information; - uint8_t du_to_cu_rrc_information_length; - f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req - uint8_t drbs_to_be_setup_length; // BK: need to replace by s1ap_initial_context_setup_req + //uint8_t *du_to_cu_rrc_information; + du_to_cu_rrc_information_t *du_to_cu_rrc_information; + uint32_t du_to_cu_rrc_information_length; + f1ap_drb_to_be_setup_t *drbs_to_be_setup; + uint8_t drbs_to_be_setup_length; + f1ap_drb_to_be_setup_t *drbs_to_be_modified; + uint8_t drbs_to_be_modified_length; + QoS_information_t QoS_information_type; uint8_t drbs_failed_to_be_setup_length; f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup; f1ap_srb_to_be_setup_t *srbs_to_be_setup; uint8_t srbs_to_be_setup_length; uint8_t srbs_failed_to_be_setup_length; f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup; - s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req; - // coniatner for the rrc_eNB_generate_SecurityModeCommand message + ReconfigurationCompl_t ReconfigComplOutcome; uint8_t *rrc_container; int rrc_container_length; } f1ap_ue_context_setup_t; -typedef struct f1ap_ue_context_setup_resp_s { - uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti - uint32_t gNB_DU_ue_id; - uint16_t rnti; - uint8_t du_to_cu_rrc_information[1024 /*Arbitrarily big enough*/]; - uint32_t du_to_cu_rrc_information_length; - f1ap_drb_to_be_setup_t *drbs_setup; // BK: need to replace by s1ap_initial_context_setup_req - uint8_t drbs_setup_length; // BK: need to replace by s1ap_initial_context_setup_req - f1ap_srb_to_be_setup_t *srbs_setup; - uint8_t srbs_setup_length; - uint8_t srbs_failed_to_be_setup_length; - f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup; - uint8_t drbs_failed_to_be_setup_length; - f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup; -} f1ap_ue_context_setup_resp_t; - typedef enum F1ap_Cause_e { F1AP_CAUSE_NOTHING, /* No components present */ F1AP_CAUSE_RADIO_NETWORK, diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 44e9d4fbdf..e0e5db5b7f 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -27,4 +27,5 @@ MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd) MESSAGE_DEF(GTPV1U_REQ, MESSAGE_PRIORITY_MED, Gtpv1uReq, gtpv1uReq) -MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_DU_BUFFER_REPORT_REQ, MESSAGE_PRIORITY_MED, gtpv1u_DU_buffer_report_req_t, NRGtpv1uBufferReportReq) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 096f0f4697..7758395ee4 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -39,6 +39,8 @@ #define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq +#define GTPV1U_DU_BUFFER_REPORT_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uBufferReportReq + #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF typedef struct gtpv1u_enb_create_x2u_tunnel_req_s { @@ -179,6 +181,7 @@ typedef struct gtpv1u_gnb_create_tunnel_req_s { int num_tunnels; //teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; + int outgoing_qfi[NR_GTPV1U_MAX_BEARERS_PER_UE]; pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; //ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; @@ -213,4 +216,10 @@ typedef struct gtpv1u_gnb_tunnel_data_req_s { pdusessionid_t pdusession_id; } gtpv1u_gnb_tunnel_data_req_t; +typedef struct gtpv1u_DU_buffer_report_req_s { + uint32_t buffer_availability; + rnti_t rnti; + pdusessionid_t pdusession_id; +} gtpv1u_DU_buffer_report_req_t; + #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/mac_rlc_primitives.h b/openair2/COMMON/mac_rlc_primitives.h index 4e3e22781c..3d6dcc8100 100644 --- a/openair2/COMMON/mac_rlc_primitives.h +++ b/openair2/COMMON/mac_rlc_primitives.h @@ -145,7 +145,7 @@ struct mac_tx_tb_management { struct mac_rx_tb_management { unsigned char *data_ptr; tb_size_t tb_size; // in bits - boolean_t valid_checksum; + bool valid_checksum; unsigned char first_bit; // 0 if data starts on byte boundary(b7), 1 if b6, 2 if b5, etc }; diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 67300da308..f229721993 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -32,35 +32,12 @@ #if !defined(NAS_NETLINK) #include +#include #else #include typedef void * intptr_t; #endif -//----------------------------------------------------------------------------- -// GENERIC TYPES -//----------------------------------------------------------------------------- - -/* boolean_t is also defined in openair2/COMMON/commonDef.h, - * let's protect potential redefinition - */ -#ifndef _BOOLEAN_T_DEFINED_ - #define _BOOLEAN_T_DEFINED_ - - typedef signed char boolean_t; - - #if !defined(TRUE) - #define TRUE (boolean_t)0x01 - #endif - - #if !defined(FALSE) - #define FALSE (boolean_t)0x00 - #endif - - #define BOOL_NOT(b) (b^TRUE) - -#endif /* _BOOLEAN_T_DEFINED_ */ - //----------------------------------------------------------------------------- // GENERIC ACCESS STRATUM TYPES //----------------------------------------------------------------------------- @@ -77,25 +54,25 @@ typedef int16_t smodule_id_t; typedef long rb_id_t; typedef long srb_id_t; -typedef boolean_t MBMS_flag_t; -#define MBMS_FLAG_NO FALSE -#define MBMS_FLAG_YES TRUE +typedef bool MBMS_flag_t; +#define MBMS_FLAG_NO false +#define MBMS_FLAG_YES true -typedef boolean_t eNB_flag_t; -#define ENB_FLAG_NO FALSE -#define ENB_FLAG_YES TRUE +typedef bool eNB_flag_t; +#define ENB_FLAG_NO false +#define ENB_FLAG_YES true -typedef boolean_t gNB_flag_t; -#define GNB_FLAG_NO FALSE -#define GNB_FLAG_YES TRUE +typedef bool gNB_flag_t; +#define GNB_FLAG_NO false +#define GNB_FLAG_YES true -typedef boolean_t srb_flag_t; -#define SRB_FLAG_NO FALSE -#define SRB_FLAG_YES TRUE +typedef bool srb_flag_t; +#define SRB_FLAG_NO false +#define SRB_FLAG_YES true -typedef boolean_t sl_discovery_flag_t; -#define SL_DISCOVERY_FLAG_NO FALSE -#define SL_DISCOVERY_FLAG_YES TRUE +typedef bool sl_discovery_flag_t; +#define SL_DISCOVERY_FLAG_NO false +#define SL_DISCOVERY_FLAG_YES true typedef enum link_direction_e { UNKNOWN_DIR = 0, @@ -152,8 +129,8 @@ typedef uint16_t rlc_usn_t; typedef int32_t rlc_buffer_occupancy_t; typedef signed int rlc_op_status_t; -#define SDU_CONFIRM_NO FALSE -#define SDU_CONFIRM_YES TRUE +#define SDU_CONFIRM_NO false +#define SDU_CONFIRM_YES true //----------------------------------------------------------------------------- // PDCP TYPES //----------------------------------------------------------------------------- @@ -242,7 +219,7 @@ typedef struct protocol_ctxt_s { frame_t frame; /*!< \brief LTE frame number.*/ sub_frame_t subframe; /*!< \brief LTE sub frame number.*/ eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */ - boolean_t brOption; + bool brOption; } protocol_ctxt_t; // warning time hardcoded #define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 67b0b610cc..18e7c4bd18 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -417,7 +417,6 @@ typedef struct NRRrcConfigurationReq_s { uint8_t num_plmn; NR_ServingCellConfigCommon_t *scc; NR_ServingCellConfig_t *scd; - int ssb_SubcarrierOffset; int sib1_tda; rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts; int pusch_AntennaPorts; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index f4550f63a1..00ffd4cc13 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -583,9 +583,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = true; } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", @@ -689,9 +689,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = true; } else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", @@ -702,9 +702,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = true; } else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -723,9 +723,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = true; } else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -766,15 +766,15 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration); if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= true; } else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_enable); - if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) { + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== true) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig; if ((ccparams_lte.srs_BandwidthConfig < 0) || @@ -791,18 +791,18 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RC.config_file_name, i, ccparams_lte.srs_SubframeConfig); if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= true; } else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_ackNackST); if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= true; } else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", @@ -921,7 +921,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles); if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= true; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1; if ((ccparams_lte.rach_numberOfRA_Preambles <4) || @@ -976,7 +976,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB); } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", @@ -1254,9 +1254,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL); else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = true; } else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = false; } else { AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n", diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c index 2e71f17e9d..e4ff458886 100644 --- a/openair2/ENB_APP/enb_config_eMTC.c +++ b/openair2/ENB_APP/enb_config_eMTC.c @@ -61,18 +61,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->cellSelectionInfoCE_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).q_RxLevMinCE_r13[cc_idx]= eMTCconfig->q_RxLevMinCE_r13; // RRC_CONFIGURATION_REQ(msg_p).q_QualMinRSRQ_CE_r13[cc_idx]= calloc(1, sizeof(long)); // *RRC_CONFIGURATION_REQ(msg_p).q_QualMinRSRQ_CE_r13[cc_idx]= q_QualMinRSRQ_CE_r13; } else { - RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = false; } if (!strcmp(eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = true; @@ -106,7 +106,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } } else { - RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = false; } char schedulingInfoBrPath[MAX_OPTNAME_SIZE * 2]; @@ -127,10 +127,10 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = CALLOC(1, sizeof(BOOLEAN_t)); if (!strcmp(eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_r13, "subframePattern40-r13")) { - *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = FALSE; + *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = false; RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13; } else { - *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = TRUE; + *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13; } @@ -156,18 +156,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->freqHoppingParametersDL_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = true; if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeA_r13, "interval-TDD-r13")) - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = false; else - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeA_r13_val; if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeB_r13, "interval-TDD-r13")) - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = false; else - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeB_r13_val; RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = calloc(1, sizeof(long)); @@ -188,7 +188,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else { - RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = false; } /** ------------------------------SIB2/3 BR------------------------------------------ */ @@ -213,9 +213,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PRACH_HIGH_SPEED); else if (strcmp(eMTCconfig->ccparams.prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = true; } else if (strcmp(eMTCconfig->ccparams.prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", @@ -310,9 +310,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); else if (strcmp(eMTCconfig->ccparams.pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = true; } else if (strcmp(eMTCconfig->ccparams.pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", @@ -323,9 +323,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); else if (strcmp(eMTCconfig->ccparams.pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled = true; } else if (strcmp(eMTCconfig->ccparams.pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -343,9 +343,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); else if (strcmp(eMTCconfig->ccparams.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = true; } else if (strcmp(eMTCconfig->ccparams.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -385,15 +385,15 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration,eMTCconfig->ccparams.phich_duration); if (strcmp(eMTCconfig->ccparams.srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= true; } else if (strcmp(eMTCconfig->ccparams.srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_enable); - if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== TRUE) { + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== true) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_BandwidthConfig= eMTCconfig->ccparams.srs_BandwidthConfig; if ((eMTCconfig->ccparams.srs_BandwidthConfig < 0) || (eMTCconfig->ccparams.srs_BandwidthConfig >7)) @@ -408,18 +408,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in config_fname, cell_idx,eMTCconfig->ccparams.srs_SubframeConfig); if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= true; } else if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_ackNackST); if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= true; } else if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", @@ -535,7 +535,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in config_fname, cell_idx,eMTCconfig->ccparams.rach_numberOfRA_Preambles); if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= true; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_sizeOfRA_PreamblesGroupA= (eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA/4)-1; if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles>60) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0)) @@ -588,7 +588,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_messagePowerOffsetGroupB); } else if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", @@ -847,14 +847,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->prach_ConfigCommon_v1310, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = TRUE; + RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = true; RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = calloc(1, sizeof(BOOLEAN_t)); if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13, "tdd-r13")) { - *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = FALSE; + *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = false; } else { - *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = TRUE; + *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = true; } if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1")) { @@ -882,7 +882,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_HoppingOffset_r13 = calloc(1, sizeof(long)); *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_HoppingOffset_r13 = eMTCconfig->prach_HoppingOffset_r13; } else { - RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = FALSE; + RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = false; } @@ -1169,7 +1169,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in /** PCCH CONFIG V1310 */ - RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).paging_narrowbands_r13[cc_idx] = eMTCconfig->paging_narrowbands_r13; RRC_CONFIGURATION_REQ(msg_p).mpdcch_numrepetition_paging_r13[cc_idx] = eMTCconfig->mpdcch_numrepetition_paging_r13; @@ -1220,7 +1220,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in /** SIB2 FREQ HOPPING PARAMETERS R13 */ - RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = true; char sib2FreqHoppingParametersR13Path[MAX_OPTNAME_SIZE*2 + 16]; sprintf(sib2FreqHoppingParametersR13Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 9926ec9e20..3113c07798 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -127,7 +127,7 @@ int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) { /* get the (active) UE with RNTI i */ for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == TRUE + if (RC.mac[mod_id]->UE_info.active[n] == true && rnti == UE_RNTI(mod_id, n)) { return n; } @@ -143,7 +143,7 @@ int flexran_get_mac_ue_id(mid_t mod_id, int i) { /* get the (i+1)'th active UE */ for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == TRUE) { + if (RC.mac[mod_id]->UE_info.active[n] == true) { if (i == 0) return n; @@ -580,7 +580,7 @@ uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) { Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; - if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == TRUE) + if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == true) return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; else return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; @@ -3585,7 +3585,7 @@ int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__Fl int CC_id, BOOLEAN_t brOption, RrcConfigurationReq *configuration); - carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf); + carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, false, conf); if (carrier->sizeof_SIB1 < 0) return -1337; /* SIB1 encoding failed, hell will probably break loose */ diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index 9085fdb57c..22627c8d92 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -32,18 +32,22 @@ void apply_macrlc_config(gNB_RRC_INST *rrc, abort(); } -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id) { +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id) { abort(); } + +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { + abort(); +} diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index 338b5f0c2b..efcb1d161b 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -35,27 +35,6 @@ static f1ap_cudu_inst_t *f1_du_inst[NUMBER_OF_eNB_MAX]= {0}; static f1ap_cudu_inst_t *f1_cu_inst[NUMBER_OF_eNB_MAX]= {0}; -#if defined(EMIT_ASN_DEBUG_EXTERN) -int asn_debug = 0; -int asn1_xer_print = 0; - -inline void ASN_DEBUG(const char *fmt, ...) { - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) - fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - uint8_t F1AP_get_next_transaction_identifier(instance_t enb_mod_idP, instance_t cu_mod_idP) { static uint8_t transaction_identifier[NUMBER_OF_eNB_MAX]; transaction_identifier[enb_mod_idP+cu_mod_idP] = diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index 66451530a6..e89e8a70cc 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -29,11 +29,6 @@ * \note * \warning */ - -#if HAVE_CONFIG_H_ - #include "config.h" -#endif - #ifndef F1AP_COMMON_H_ #define F1AP_COMMON_H_ @@ -43,10 +38,6 @@ #define F1AP_UE_IDENTIFIER_NUMBER 3 #define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3 -#if defined(EMIT_ASN_DEBUG_EXTERN) - inline void ASN_DEBUG(const char *fmt, ...); -#endif - #include "F1AP_RAT-FrequencyPriorityInformation.h" #include "F1AP_DLUPTNLInformation-ToBeSetup-Item.h" #include "F1AP_PrivateMessage.h" @@ -363,13 +354,6 @@ # error "You are compiling f1ap with the wrong version of ASN1C" #endif -#ifndef FALSE - #define FALSE (0) -#endif -#ifndef TRUE - #define TRUE (!FALSE) -#endif - #define F1AP_UE_ID_FMT "0x%06"PRIX32 #include "assertions.h" diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 62a62095b1..3ae30cafb9 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -79,56 +79,60 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true); rnti = ie->value.choice.C_RNTI; - /* RRC Container */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_InitialULRRCMessageTransferIEs_t *rrccont; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); - AssertFatal(ie!=NULL,"RRCContainer is missing\n"); + AssertFatal(rrccont!=NULL,"RRCContainer is missing\n"); - // create an ITTI message and copy SDU - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, NR_RRC_MAC_CCCH_DATA_IND); - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = ie->value.choice.RRCContainer.size; - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, - ccch_sdu_len); - } else { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = ie->value.choice.RRCContainer.size; - memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, - ccch_sdu_len); - } - - LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, ie->value.choice.RRCContainer.size); - /* DUtoCURRCContainer */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_InitialULRRCMessageTransferIEs_t *du2cu; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); - if (ie) { - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = ie->value.choice.DUtoCURRCContainer.size; - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(ie->value.choice.DUtoCURRCContainer.size); - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, - ie->value.choice.DUtoCURRCContainer.buf, - ie->value.choice.DUtoCURRCContainer.size); - } - int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti); if (f1ap_uid < 0 ) { LOG_E(F1AP, "Failed to add UE \n"); - itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } + // create an ITTI message and copy SDU + if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { + message_p = itti_alloc_new_message (TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); + ul_rrc->nr_cellid = nr_cellid; // CU instance + ul_rrc->crnti = rnti; + ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; + ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); + memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); + AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); + ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; + ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); + } else { + message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + ccch_sdu_len = rrccont->value.choice.RRCContainer.size; + memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf, + ccch_sdu_len); + NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; + NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance + NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; + NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; + if (du2cu) { + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size; + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(du2cu->value.choice.DUtoCURRCContainer.size); + memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, + du2cu->value.choice.DUtoCURRCContainer.buf, + du2cu->value.choice.DUtoCURRCContainer.size); + } + itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p); + } + //getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; - NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; - NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; - itti_send_msg_to_task (f1ap_req(true,ITTI_MSG_DESTINATION_ID(message_p))->cell_type==CELL_MACRO_GNB?TASK_RRC_GNB:TASK_RRC_ENB, instance, message_p); return 0; } diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index b3c7363ca4..b521d0c83d 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -172,6 +172,7 @@ void *F1AP_CU_task(void *arg) { LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n"); CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_DL_RRC_MESSAGE(received_msg)); + free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); break; case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc @@ -180,6 +181,12 @@ void *F1AP_CU_task(void *arg) { &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_REQ: + LOG_I(F1AP, "CU Task received F1AP_UE_CONTEXT_MODIFICATION_REQ\n"); + CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); + break; + case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n"); CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index c68bfb3852..cf8d4ce260 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -131,21 +131,30 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie6->criticality = F1AP_Criticality_reject; ie6->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation; - /* optional */ - /* 6.1 cG_ConfigInfo */ - if (0) { - const char cG_ConfigInfoStr[]="asdsa1d32sa1d31asd31as"; - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); - OCTET_STRING_fromBuf(cG_ConfigInfo, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if (f1ap_ue_context_setup_req->cu_to_du_rrc_information!=NULL) { + /* optional */ + /* 6.1 cG_ConfigInfo */ + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); + OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo_length); + } /* optional */ /* 6.2 uE_CapabilityRAT_ContainerList */ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); - OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); + OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + } /* optional */ /* 6.3 measConfig */ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); - OCTET_STRING_fromBuf(measConfig, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); + OCTET_STRING_fromBuf(measConfig, (const char*)f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig_length); + } } + /* mandatory */ /* c7. Candidate_SpCell_List */ @@ -238,199 +247,96 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* mandatory */ /* c11. SRBs_ToBeSetup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; - ie11->criticality = F1AP_Criticality_reject; // ? - ie11->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; + if(f1ap_ue_context_setup_req->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11); + ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; + ie11->criticality = F1AP_Criticality_reject; // ? + ie11->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; - for (int i=0; isrbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies); - srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 - srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; - /* 11.1 SRBs_ToBeSetup_Item */ - F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item; - /* 11.1.1 sRBID */ - srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id; - /* OPTIONAL */ - /* 11.1.2 duplicationIndication */ - //if (0) { - asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication, + for (int i=0; isrbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies); + srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 + srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; + /* 11.1 SRBs_ToBeSetup_Item */ + F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item; + /* 11.1.1 sRBID */ + srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id; + /* OPTIONAL */ + /* 11.1.2 duplicationIndication */ + asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication, F1AP_DuplicationIndication_true); // enum - //} + } } /* mandatory */ /* c12. DRBs_ToBeSetup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; - LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length); + if(f1ap_ue_context_setup_req->drbs_to_be_setup_length){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; + ie12->criticality = F1AP_Criticality_reject; + ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; + LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length); - for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); - drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; - drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; - /* 12.1 DRBs_ToBeSetup_Item */ - F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; - /* 12.1.1 dRBID */ - drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 - /* 12.1.2 qoSInformation */ - int some_decide_qos = 0; // BK: Need Check + for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); + drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; + drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; + /* 12.1 DRBs_ToBeSetup_Item */ + F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; + /* 12.1.1 dRBID */ + drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 + /* 12.1.2 qoSInformation */ + int some_decide_qos = 0; // BK: Need Check - if (some_decide_qos) { - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - /* 12.1.2.1 eUTRANQoS */ - asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS); - /* 12.1.2.1.1 qCI */ - eUTRANQoS->qCI = 254L; - /* 12.1.2.1.2 allocationAndRetentionPriority */ - { - /* 12.1.2.1.2.1 priorityLevel */ - eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - /* 12.1.2.1.2.2 pre_emptionCapability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum - /* 12.1.2.1.2.2 pre_emptionVulnerability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } - - /* OPTIONAL */ - /* 12.1.2.1.3 gbrQosInformation */ - if (0) { - eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); - } - } else { - /* 12.1.2 DRB_Information */ - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; - F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); - ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; - ie->criticality = F1AP_Criticality_reject; - ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; - F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; - drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; - /* 12.1.2.1 dRB_QoS */ - { - /* qoS_Characteristics */ + if (some_decide_qos) { + drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + /* 12.1.2.1 eUTRANQoS */ + asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS); + /* 12.1.2.1.1 qCI */ + eUTRANQoS->qCI = 254L; + /* 12.1.2.1.2 allocationAndRetentionPriority */ { - int some_decide_qoS_characteristics = 0; // BK: Need Check - - if (some_decide_qoS_characteristics) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } + /* 12.1.2.1.2.1 priorityLevel */ + eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + /* 12.1.2.1.2.2 pre_emptionCapability */ + eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum + /* 12.1.2.1.2.2 pre_emptionVulnerability */ + eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum } /* OPTIONAL */ - /* reflective_QoS_Attribute */ + /* 12.1.2.1.3 gbrQosInformation */ if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); + eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); } - } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); - - /* OPTIONAL */ - /* sD */ - if (0) { - asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } - } - - /* OPTIONAL */ - /* 12.1.2.3 notificationControl */ - if (0) { - asn1cCallocOne(DRB_Information->notificationControl, - F1AP_NotificationControl_active); // enum - } - - /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - - for (int k = 0; k < 1; k ++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; - /* qoSFlowLevelQoSParameters */ + } else { + /* 12.1.2 DRB_Information */ + drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; + F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); + ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; + F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; + drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ { /* qoS_Characteristics */ { int some_decide_qoS_characteristics = 0; // BK: Need Check - F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; if (some_decide_qoS_characteristics) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(QosParams->choice.non_Dynamic_5QI); + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); /* qoSPriorityLevel */ tmp->qoSPriorityLevel = 1L; /* packetDelayBudget */ @@ -442,36 +348,33 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* OPTIONAL */ /* delayCritical */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); } /* OPTIONAL */ /* averagingWindow */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); } /* OPTIONAL */ /* maxDataBurstVolume */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); } } // if some_decide_qoS_characteristics } // qoS_Characteristics /* nGRANallocationRetentionPriority */ { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum } // nGRANallocationRetentionPriority /* OPTIONAL */ /* gBR_QoS_Flow_Information */ if (0) { - asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); @@ -480,80 +383,186 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* OPTIONAL */ /* maxPacketLossRateDownlink */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); } /* OPTIONAL */ /* maxPacketLossRateUplink */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); } } /* OPTIONAL */ /* reflective_QoS_Attribute */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); } - } // qoSFlowLevelQoSParameters - } - } // if some_decide_qos + } // dRB_QoS + /* 12.1.2.2 sNSSAI */ + { + /* sST */ + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); - /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ - for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /* Here the callback function used as input is not the right one. Need to create a new one probably for F1-U, not sure - * if the kind of input parameters to the callback function are convenient though for gtp-u over F1-U.*/ - //Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU - transport_layer_addr_t addr; - int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); - memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); - addr.length = sz*8; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid= - newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_req->rnti, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - addr, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req); - /* 12.3.1 ULTunnels_ToBeSetup_Item */ - asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - /* 12.3.1.1.1 transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, + /* OPTIONAL */ + /* sD */ + if (0) { + asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); + OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + } + } + + /* OPTIONAL */ + /* 12.1.2.3 notificationControl */ + if (0) { + asn1cCallocOne(DRB_Information->notificationControl, + F1AP_NotificationControl_active); // enum + } + + /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy + + for (int k = 0; k < 1; k ++) { + asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, + F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); + /* qoSFlowIndicator */ + flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; + /* qoSFlowLevelQoSParameters */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check + F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; + + if (some_decide_qoS_characteristics) { + QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(QosParams->choice.non_Dynamic_5QI); + } else { + QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); + *tmp= 1L; + } + } // if some_decide_qoS_characteristics + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + } + } // qoSFlowLevelQoSParameters + } + } // if some_decide_qos + + /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ + for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ + transport_layer_addr_t addr; + int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); + memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); + addr.length = sz*8; + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_setup_req->rnti, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + addr, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, + cu_f1u_data_req, + NULL); + /* 12.3.1 ULTunnels_ToBeSetup_Item */ + asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, + F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + gTPTunnel); + /* 12.3.1.1.1 transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, &gTPTunnel->transportLayerAddress); - /* 12.3.1.1.2 gTP_TEID */ - INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, - &gTPTunnel->gTP_TEID); - } + /* 12.3.1.1.2 gTP_TEID */ + INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, + &gTPTunnel->gTP_TEID); + } - /* 12.1.4 rLCMode */ - /* TODO use rlc_mode from f1ap_drb_to_be_setup */ - switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { - case RLC_MODE_AM: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; - break; + /* 12.1.4 rLCMode */ + /* TODO use rlc_mode from f1ap_drb_to_be_setup */ + switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { + case RLC_MODE_AM: + drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; + break; - default: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; - } + default: + drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + } - /* OPTIONAL */ - /* 12.1.5 ULConfiguration */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp); - tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; - } + /* OPTIONAL */ + /* 12.1.5 ULConfiguration */ + if (0) { + asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp); + tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; + } - /* OPTIONAL */ - /* 12.1.6 duplicationActivation */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp); - *tmp = F1AP_DuplicationActivation_active; // enum + /* OPTIONAL */ + /* 12.1.6 duplicationActivation */ + if (0) { + asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp); + *tmp = F1AP_DuplicationActivation_active; // enum + } } } @@ -662,9 +671,10 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, return -1; } - f1ap_ue_context_setup_resp->du_to_cu_rrc_information = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); - memcpy(f1ap_ue_context_setup_resp->du_to_cu_rrc_information, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); - f1ap_ue_context_setup_resp->du_to_cu_rrc_information_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; + f1ap_ue_context_setup_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1,sizeof(du_to_cu_rrc_information_t)); + f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + memcpy(f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; // DRBs_Setup_List F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DRBs_Setup_List, false); @@ -896,12 +906,14 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, /* optional */ /* c4. RRCContainer */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie4->criticality = F1AP_Criticality_ignore; - ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, + if(cmd->rrc_container!=NULL){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie4->criticality = F1AP_Criticality_ignore; + ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, cmd->rrc_container_length); + } /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -961,9 +973,6 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); } -#ifdef ITTI_SIM - return 0; -#endif } else { struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], rnti); @@ -1008,7 +1017,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, return 0; } //void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) { -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; uint8_t *buffer=NULL; @@ -1029,14 +1038,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; /* optional */ /* c3. NRCGI */ @@ -1049,13 +1058,15 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { addnRCGI(ie3->value.choice.NRCGI, &hardCoded); } - /* mandatory */ + /* optional */ /* c4. ServCellIndex */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; - ie4->value.choice.ServCellIndex = 5L; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; + ie4->value.choice.ServCellIndex = 5L; + } /* optional */ /* c5. DRXCycle */ @@ -1077,47 +1088,58 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { } /* optional */ - /* c5. CUtoDURRCInformation */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; - ie5->criticality = F1AP_Criticality_reject; - ie5->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; - asn1cCalloc(ie5->value.choice.CUtoDURRCInformation.cG_ConfigInfo, tmp); - /* optional */ - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - asn1cCalloc(ie5->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, - tmp2); - /* optional */ - OCTET_STRING_fromBuf(tmp2, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } - - /* optional */ - /* c6. TransmissionActionIndicator */ - if (1) { + /* c6. CUtoDURRCInformation */ + if (f1ap_ue_context_modification_req->cu_to_du_rrc_information!=NULL) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; - ie6->criticality = F1AP_Criticality_ignore; - ie6->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; - ie6->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop; + ie6->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; + ie6->criticality = F1AP_Criticality_reject; + ie6->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; + /* 6.1 cG_ConfigInfo */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); + OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo_length); + } + /* optional */ + /* 6.2 uE_CapabilityRAT_ContainerList */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); + OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length) ; + } + /* optional */ + /* 6.3 measConfig */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); + OCTET_STRING_fromBuf(measConfig, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig_length); + } } /* optional */ - /* c7. ResourceCoordinationTransferContainer */ + /* c7. TransmissionActionIndicator */ if (0) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; - OCTET_STRING_fromBuf(&ie7->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", + ie7->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; + ie7->criticality = F1AP_Criticality_ignore; + ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; + ie7->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop; + } + + /* optional */ + /* c8. ResourceCoordinationTransferContainer */ + if (0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8); + ie8->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie8->criticality = F1AP_Criticality_ignore; + ie8->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; + OCTET_STRING_fromBuf(&ie8->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", strlen("asdsa1d32sa1d31asd31as")); } /* optional */ /* c7. RRCRconfigurationCompleteIndicator */ - if (1) { + if (f1ap_ue_context_modification_req->ReconfigComplOutcome == RRCreconf_success) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie71); ie71->id = F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator; ie71->criticality = F1AP_Criticality_ignore; @@ -1127,218 +1149,488 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { /* optional */ /* c8. RRCContainer */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie8->criticality = F1AP_Criticality_ignore; - ie8->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie8->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + if (f1ap_ue_context_modification_req->rrc_container != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie81); + ie81->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie81->criticality = F1AP_Criticality_ignore; + ie81->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie81->value.choice.RRCContainer, (const char*)f1ap_ue_context_modification_req->rrc_container, + f1ap_ue_context_modification_req->rrc_container_length); } - /* mandatory */ + /* optional */ /* c9. SCell_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9); + ie9->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; + ie9->criticality = F1AP_Criticality_ignore; + ie9->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list, F1AP_SCell_ToBeSetupMod_ItemIEs_t, scell_toBeSetupMod_item_ies); - scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; - scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; - /* 8.1 SCell_ToBeSetup_Item */ - F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item= - &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item; - // /* - sCell_ID */ - addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded); - /* sCellIndex */ - scell_toBeSetupMod_item->sCellIndex = 6; // issue here + scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; + scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item= + &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item; + // /* - sCell_ID */ + addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded); + /* sCellIndex */ + scell_toBeSetupMod_item->sCellIndex = 6; // issue here + } } - /* mandatory */ + /* optional */ /* c10. SCell_ToBeRemoved_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; - ie10->criticality = F1AP_Criticality_ignore; - ie10->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10); + ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; + ie10->criticality = F1AP_Criticality_ignore; + ie10->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list, F1AP_SCell_ToBeRemoved_ItemIEs_t, scell_toBeRemoved_item_ies); - scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; - scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; - /* 10.1 SCell_ToBeRemoved_Item */ - F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item= - &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item; - /* - sCell_ID */ - addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded); + scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; + scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; + /* 10.1 SCell_ToBeRemoved_Item */ + F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item= + &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item; + /* - sCell_ID */ + addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded); + } } /* mandatory */ /* c11. SRBs_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; - ie11->criticality = F1AP_Criticality_reject; - ie11->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; + if(f1ap_ue_context_modification_req->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11); + ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; + ie11->criticality = F1AP_Criticality_reject; + ie11->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List.list, - F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies); - srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; - srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; - /* 9.1 SRBs_ToBeSetupMod_Item */ - F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item= - &srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item; - /* - sRBID */ - srbs_toBeSetupMod_item->sRBID = 3L; + for (int i=0; isrbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List, F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies); + srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; // 73 + srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; + /* 11.1 SRBs_ToBeSetup_Item */ + F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item=&srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item; + /* 11.1.1 sRBID */ + srbs_toBeSetupMod_item->sRBID = f1ap_ue_context_modification_req->srbs_to_be_setup[i].srb_id; + /* OPTIONAL */ + /* 11.1.2 duplicationIndication */ + asn1cCallocOne(srbs_toBeSetupMod_item->duplicationIndication, + F1AP_DuplicationIndication_true); // enum + } } /* mandatory */ /* c12. DRBs_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; + if(f1ap_ue_context_modification_req->drbs_to_be_setup_length){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; + ie12->criticality = F1AP_Criticality_reject; + ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, + for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies); - drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; - drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; - /* 12.1 DRBs_ToBeSetupMod_Item */ - F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= - &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; - /* dRBID */ - drbs_toBeSetupMod_item->dRBID = 30L; - /* qoSInformation */ - drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L; - /* uLUPTNLInformation_ToBeSetup_List */ - int maxnoofULTunnels = 1; // 2; + drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; + drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; + /* 12.1 DRBs_ToBeSetupMod_Item */ + F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= + &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; + /* dRBID */ + drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id; + /* qoSInformation */ - for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, + if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){ + drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L; + /* uLUPTNLInformation_ToBeSetup_List */ + int maxnoofULTunnels = 1; // 2; + + for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, gTPTunnel) - /* transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - /* gTP_TEID */ - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", - strlen("4567")); - } + /* transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", + strlen("4567")); + } - /* rLCMode */ - drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum + /* rLCMode */ + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); - } - } + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } + } //QoS information - /* mandatory */ - /* c13. DRBs_ToBeModified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13); - ie13->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; - ie13->criticality = F1AP_Criticality_reject; - ie13->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; + else{ + /* 12.1.2 DRB_Information */ + drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; + F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); + ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; + F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; + drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list, - F1AP_DRBs_ToBeModified_ItemIEs_t, drbs_toBeModified_item_ies); - drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; - drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; - /* 13.1 SRBs_ToBeModified_Item */ - F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item= - &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item; - /* dRBID */ - drbs_toBeModified_item->dRBID = 30L; - /* qoSInformation */ - asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp); - tmp->present = F1AP_QoSInformation_PR_eUTRANQoS; - tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - tmp->choice.eUTRANQoS->qCI = 254L; - /* ULTunnels_ToBeModified_List */ - int maxnoofULTunnels = 1; // 2; + if (some_decide_qoS_characteristics) { + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); + } else { + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; - for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); + } + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); + } + } // dRB_QoS + /* 12.1.2.2 sNSSAI */ + { + /* sST */ + + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); + + /* OPTIONAL */ + /* sD */ + if (0) { + asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); + OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + } + } + + /* OPTIONAL */ + /* 12.1.2.3 notificationControl */ + if (0) { + asn1cCallocOne(DRB_Information->notificationControl, + F1AP_NotificationControl_active); // enum + } + + /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy + + for (int k = 0; k < 1; k ++) { + asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, + F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); + /* qoSFlowIndicator */ + flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; + /* qoSFlowLevelQoSParameters */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check + F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; + + if (some_decide_qoS_characteristics) { + QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(QosParams->choice.non_Dynamic_5QI); + } else { + QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); + *tmp= 1L; + } + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + } + } // qoSFlowLevelQoSParameters + } + + } //QoS information + + /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ + for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ + transport_layer_addr_t addr; + int sz=sizeof(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); + memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); + addr.length = sz*8; + + f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_modification_req->rnti, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + addr, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port, + cu_f1u_data_req, + NULL); + /* 12.3.1 ULTunnels_ToBeSetup_Item */ + asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + gTPTunnel); + /* 12.3.1.1.1 transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, + &gTPTunnel->transportLayerAddress); + /* 12.3.1.1.2 gTP_TEID */ + INT32_TO_OCTET_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, + &gTPTunnel->gTP_TEID); + } + /* 12.1.4 rLCMode */ + /* TODO use rlc_mode from f1ap_drb_to_be_setup */ + switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) { + case RLC_MODE_AM: + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am; + break; + + default: + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + } + + /* OPTIONAL */ + /* 12.1.5 ULConfiguration */ + if (0) { + asn1cCalloc(drbs_toBeSetupMod_item->uLConfiguration, tmp); + tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; + } + + /* OPTIONAL */ + /* 12.1.6 duplicationActivation */ + if (0) { + asn1cCalloc(drbs_toBeSetupMod_item->duplicationActivation, tmp); + *tmp = F1AP_DuplicationActivation_active; // enum + } + } + } + + /* optional */ + if(0){ + /* c13. DRBs_ToBeModified_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13); + ie13->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; + ie13->criticality = F1AP_Criticality_reject; + ie13->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; + + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list, + F1AP_DRBs_ToBeModified_ItemIEs_t, drbs_toBeModified_item_ies); + drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; + drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; + /* 13.1 SRBs_ToBeModified_Item */ + F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item= + &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item; + /* dRBID */ + drbs_toBeModified_item->dRBID = 30L; + /* qoSInformation */ + asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp); + tmp->present = F1AP_QoSInformation_PR_eUTRANQoS; + tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + tmp->choice.eUTRANQoS->qCI = 254L; + /* ULTunnels_ToBeModified_List */ + int maxnoofULTunnels = 1; // 2; + + for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, + F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", strlen("1204")); - } + } - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } } } - /* mandatory */ - /* c14. SRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14); - ie14->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; - ie14->criticality = F1AP_Criticality_reject; - ie14->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; + /* optional */ + if(0){ + /* c14. SRBs_ToBeReleased_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14); + ie14->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; + ie14->criticality = F1AP_Criticality_reject; + ie14->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list, F1AP_SRBs_ToBeReleased_ItemIEs_t, srbs_toBeReleased_item_ies); - srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; - srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; - /* 9.1 SRBs_ToBeReleased_Item */ - F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item= - &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item; - /* - sRBID */ - srbs_toBeReleased_item->sRBID = 2L; + srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; + srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; + /* 9.1 SRBs_ToBeReleased_Item */ + F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item= + &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item; + /* - sRBID */ + srbs_toBeReleased_item->sRBID = 2L; + } } - /* mandatory */ - /* c15. DRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15); - ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; - ie15->criticality = F1AP_Criticality_reject; - ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; + /* optional */ + if(0){ + /* c15. DRBs_ToBeReleased_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15); + ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; + ie15->criticality = F1AP_Criticality_reject; + ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list, F1AP_DRBs_ToBeReleased_ItemIEs_t, drbs_toBeReleased_item_ies); - drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; - drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; - /* 14.1 SRBs_ToBeReleased_Item */ - F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item= - &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; - /* dRBID */ - drbs_toBeReleased_item->dRBID = 30L; + drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; + drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; + /* 14.1 SRBs_ToBeReleased_Item */ + F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item= + &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; + /* dRBID */ + drbs_toBeReleased_item->dRBID = 30L; + } } /* encode */ @@ -1346,7 +1638,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); return -1; } - + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0 /* BK: fix me*/); return 0; } @@ -1354,7 +1646,130 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + + MessageDef *msg_p; + F1AP_UEContextModificationResponse_t *container; + F1AP_UEContextModificationResponseIEs_t *ie; + DevAssert(pdu); + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_setup_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); + container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; + int i; + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); + + f1ap_ue_context_modification_resp->rnti = + f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id); + + // DUtoCURRCInformation + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1, sizeof(du_to_cu_rrc_information_t)); + f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + + memcpy(f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; + } + + // DRBs_SetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_SetupMod_List.list.count; + f1ap_ue_context_modification_resp->drbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_to_be_setup_length, + sizeof(f1ap_drb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->drbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->drbs_to_be_setup_length; ++i) { + f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_to_be_setup[i]; + F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item_p; + drbs_setupmod_item_p = &((F1AP_DRBs_SetupMod_ItemIEs_t *)ie->value.choice.DRBs_SetupMod_List.list.array[i])->value.choice.DRBs_SetupMod_Item; + drb_p->drb_id = drbs_setupmod_item_p->dRBID; + // TODO in the following, assume only one UP UL TNL is present. + // this matches/assumes OAI CU/DU implementation, can be up to 2! + drb_p->up_dl_tnl_length = 1; + AssertFatal(drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0, + "no DL UP TNL Information in DRBs to be Setup list\n"); + F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0]; + F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); + OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); + GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_modification_resp->rnti, + (ebi_t)drbs_setupmod_item_p->dRBID, + drb_p->up_dl_tnl[0].teid); + } + } + // SRBs_FailedToBeSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetupMod_List.list.count; + f1ap_ue_context_modification_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length, + sizeof(f1ap_rb_failed_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length; ++i) { + f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_failed_to_be_setup[i]; + srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.SRBs_FailedToBeSetupMod_List.list.array[i])->sRBID; + } + + } + // DRBs_FailedToBeSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetupMod_List.list.count; + f1ap_ue_context_modification_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length, + sizeof(f1ap_rb_failed_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length; ++i) { + f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_failed_to_be_setup[i]; + drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.DRBs_FailedToBeSetupMod_List.list.array[i])->dRBID; + } + } + + // SCell_FailedtoSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List, false); + if(ie!=NULL){ + LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetupMod_List \n"); + } + + // SRBs_Setup_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_SetupMod_List.list.count; + f1ap_ue_context_modification_resp->srbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_to_be_setup_length, + sizeof(f1ap_srb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->srbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->srbs_to_be_setup_length; ++i) { + f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_to_be_setup[i]; + F1AP_SRBs_SetupMod_Item_t *srbs_setup_item_p; + srbs_setup_item_p = &((F1AP_SRBs_SetupMod_ItemIEs_t *)ie->value.choice.SRBs_SetupMod_List.list.array[i])->value.choice.SRBs_SetupMod_Item; + srb_p->srb_id = srbs_setup_item_p->sRBID; + srb_p->lcid = srbs_setup_item_p->lCID; + } + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; } int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 09af51ec54..87563e97b1 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -72,7 +72,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + f1ap_ue_context_setup_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c index 6ebf1cc16d..60b3f94310 100644 --- a/openair2/F1AP/f1ap_decoder.c +++ b/openair2/F1AP/f1ap_decoder.c @@ -78,6 +78,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) { case F1AP_ProcedureCode_id_UEContextSetup: LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__); break; + + case F1AP_ProcedureCode_id_UEContextModification: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); + break; // case F1AP_ProcedureCode_id_InitialContextSetup: // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); @@ -123,6 +127,10 @@ static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu) { LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__); break; + case F1AP_ProcedureCode_id_UEContextModification: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); + break; + default: LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome->procedureCode); diff --git a/openair2/F1AP/f1ap_default_values.h b/openair2/F1AP/f1ap_default_values.h index 91a1179624..7c64614f50 100644 --- a/openair2/F1AP/f1ap_default_values.h +++ b/openair2/F1AP/f1ap_default_values.h @@ -40,7 +40,7 @@ #define ENB_NAME "Eurecom ENB" #define ENB_NAME_FORMAT (ENB_NAME" %u") -#define F1AP_PORT_NUMBER (30923) +#define F1AP_PORT_NUMBER (38472) #define F1AP_SCTP_PPID (62) #endif /* F1AP_DEFAULT_VALUES_H_ */ diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 6d4757be6f..367b71fed5 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -172,7 +172,20 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) { MCC_MNC_TO_PLMNID(cell->mcc, cell->mnc, cell->mnc_digit_length, &servedPLMN_item->pLMN_Identity); // // /* - CHOICE NR-MODE-Info */ F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info; + F1AP_ProtocolExtensionContainer_154P34_t *p_154P34=calloc(1,sizeof(* p_154P34)); + servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p_154P34; + asn1cSequenceAdd(p_154P34->list, F1AP_ServedPLMNs_ItemExtIEs_t , served_plmns_itemExtIEs); + served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore; + served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList; + served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; + F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; + asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, SliceSupport_item); + INT8_TO_OCTET_STRING(1,&SliceSupport_item->sNSSAI.sST); + asn1cCalloc(SliceSupport_item->sNSSAI.sD, tmp); + INT24_TO_OCTET_STRING(10203,tmp); + //INT24_TO_OCTET_STRING(1,tmp); + if (f1ap_req(false, instance)->fdd_flag) { // FDD nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 90ea324a28..c0f8b79839 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -56,6 +56,7 @@ #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, uint32_t assoc_id, @@ -509,7 +510,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id); rlc_op_status_t rlc_status; - boolean_t ret = TRUE; + bool ret = true; mem_block_t *pdcp_pdu_p = NULL; pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__); @@ -539,27 +540,27 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, switch (rlc_status) { case RLC_OP_STATUS_OK: //LOG_I(F1AP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; + ret= false; break; default: LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; + ret= false; break; } // switch case @@ -667,9 +668,9 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received + if (UE_scheduling_control->cdrx_waiting_ack == true) { + UE_scheduling_control->cdrx_waiting_ack = false; + UE_scheduling_control->cdrx_configured = true; // Set to TRUE when RRC Connection Reconfiguration Complete is received LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } @@ -748,7 +749,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, rnti_t rntiP, const uint8_t *sduP, sdu_size_t sdu_lenP, - const char *sdu2P, + const uint8_t *sdu2P, sdu_size_t sdu2_lenP) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; @@ -807,9 +808,16 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie5->criticality = F1AP_Criticality_reject; ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, - sdu2P, + (const char *)sdu2P, sdu2_lenP); } + /* mandatory */ + /* c6. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie6->criticality = F1AP_Criticality_ignore; + ie6->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID; + ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(f1ap_req(false, instanceP)->gNB_DU_id, f1ap_req(false, instanceP)->gNB_DU_id); /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -979,6 +987,16 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, } } + f1ap_dl_rrc_message_t dl_rrc = { + .rrc_container_length = ie->value.choice.RRCContainer.size, + .rrc_container = ie->value.choice.RRCContainer.buf, + .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id), + .srb_id = srb_id + }; + int rc = dl_rrc_message(instance, &dl_rrc); + if (rc == 0) + return 0; /* has been handled, otherwise continue below */ + // decode RRC Container and act on the message type AssertFatal(srb_id<3,"illegal srb_id\n"); MessageDef *msg = itti_alloc_new_message(TASK_DU_F1, 0, NR_DU_RRC_DL_INDICATION); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index d6f196e384..b42d731ac7 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -50,7 +50,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, rnti_t rntiP, const uint8_t *sduP, sdu_size_t sdu_lenP, - const char *sdu2P, + const uint8_t *sdu2P, sdu_size_t sdu2_lenP); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index c8cfadb999..f8cf216220 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -126,7 +126,7 @@ void *F1AP_DU_task(void *arg) { LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg); createF1inst(false, myInstance, msgSetup); - getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, + getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, //"172.21.6.9", //"172.21.10.9",//"172.21.9.5", //msgSetup->CU_f1_ip_address.ipv4_address, //"192.168.18.91" msgSetup->CUport, msgSetup->DU_f1_ip_address.ipv4_address, msgSetup->DUport); @@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_UL_RRC_MESSAGE: // to rrc - LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); + LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) { DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, @@ -191,6 +191,11 @@ void *F1AP_DU_task(void *arg) { DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_RESP: + LOG_I(F1AP, "DU task received itti message from RRC for F1AP_UE_CONTEXT_MODIFICATION_RESP message generation \n"); + DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); + break; + case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n"); DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e19f077592..cb15862921 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -42,16 +42,16 @@ #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include -boolean_t lteDURecvCb( protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool lteDURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); @@ -131,6 +131,19 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->cellULConfigured = NULL; } + F1AP_UEContextSetupRequestIEs_t *ieCuRrcInfo; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieCuRrcInfo, container, + F1AP_ProtocolIE_ID_id_CUtoDURRCInformation, false); + if(ieCuRrcInfo!=NULL){ + f1ap_ue_context_setup_req->cu_to_du_rrc_information = (cu_to_du_rrc_information_t *)calloc(1,sizeof(cu_to_du_rrc_information_t)); + if(ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList!=NULL){ + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); + memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size; + LOG_I(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + } + } + /* DRB */ F1AP_UEContextSetupRequestIEs_t *ieDrb; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDrb, container, @@ -174,14 +187,16 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, transport_layer_addr_t addr; memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address)); addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8; - drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT, - f1ap_ue_context_setup_req->rnti, - drb_p->drb_id, - drb_p->drb_id, - drb_p->up_ul_tnl[0].teid, - addr, - drb_p->up_ul_tnl[0].port, - lteDURecvCb); + drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT, + f1ap_ue_context_setup_req->rnti, + drb_p->drb_id, + drb_p->drb_id, + drb_p->up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p->up_ul_tnl[0].port, + lteDURecvCb, + NULL); drb_p->up_dl_tnl_length++; } } @@ -218,17 +233,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size); memcpy(f1ap_ue_context_setup_req->rrc_container, ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + f1ap_ue_context_setup_req->rrc_container_length = ieRRC->value.choice.RRCContainer.size; // AssertFatal(0, "check configuration, send to appropriate handler\n"); - protocol_ctxt_t ctxt; - // decode RRC Container and act on the message type - //FIXME - //rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id); - ctxt.instance = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; - mem_block_t *pdcp_pdu_p = get_free_mem_block(ieRRC->value.choice.RRCContainer.size, __func__); - memcpy(&pdcp_pdu_p->data[0], ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); - du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, ieRRC->value.choice.RRCContainer.size, pdcp_pdu_p); } else { LOG_E(F1AP, " RRCContainer in UEContextSetupRequestIEs size id 0\n"); } @@ -245,7 +251,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, return 0; } -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req) { +int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextSetupResponse_t *out; uint8_t *buffer=NULL; @@ -264,41 +270,42 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id; + ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, req->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + /* mandatory */ /* c3. DUtoCURRCInformation */ - //if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation; - { - /* cellGroupConfig */ - OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)req->du_to_cu_rrc_information, - req->du_to_cu_rrc_information_length); + if(resp->du_to_cu_rrc_information){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation; + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + /* cellGroupConfig */ + OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + } /* OPTIONAL */ /* measGapConfig */ - if (0) { - asn1cCalloc(ie3->value.choice.DUtoCURRCInformation.measGapConfig, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa", strlen("asdsa")); + if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig, + resp->du_to_cu_rrc_information->measGapConfig_length); } /* OPTIONAL */ /* requestedP_MaxFR1 */ - if (0) { - asn1cCalloc(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa", strlen("asdsa")); + if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1, + resp->du_to_cu_rrc_information->requestedP_MaxFR1_length); } } - //} /* optional */ /* c4. C_RNTI */ @@ -308,7 +315,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie4->criticality = F1AP_Criticality_ignore; ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI; //C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); - ie4->value.choice.C_RNTI=req->rnti; + ie4->value.choice.C_RNTI=resp->rnti; LOG_E(F1AP,"RNTI to code!\n"); } @@ -335,46 +342,48 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* mandatory */ /* c7. DRBs_Setup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List; - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; - - for (int i=0; i< req->drbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, - F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); - drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item; - drbs_setup_item_ies->criticality = F1AP_Criticality_ignore; - drbs_setup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; - /* 7.1 DRBs_Setup_Item */ - /* ADD */ - F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; - /* dRBID */ - drbs_setup_item->dRBID = req->drbs_to_be_setup[i].drb_id; - - /* OPTIONAL */ - /* lCID */ - //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); - //drbs_setup_item.lCID = 1L; - - for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + if(resp->drbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie7); + ie7->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List; + ie7->criticality = F1AP_Criticality_ignore; + ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; + for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, + F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); + drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item; + drbs_setup_item_ies->criticality = F1AP_Criticality_ignore; + drbs_setup_item_ies->value.present = F1AP_DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item; + /* 7.1 DRBs_Setup_Item */ /* ADD */ - asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, + F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; + /* dRBID */ + drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id; + + /* OPTIONAL */ + /* lCID */ + //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); + //drbs_setup_item.lCID = 1L; + + for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + /* ADD */ + asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - /* gTPTunnel */ - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); - /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, - &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); - /* gTP_TEID */ - INT32_TO_OCTET_STRING(req->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); - } // for j - } // for i + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + /* gTPTunnel */ + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, + &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } // for j + } // for i + + } /* mandatory */ /* c8. SRBs_FailedToBeSetup_List */ @@ -387,7 +396,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup for (int i=0; i<1; i++) { // asn1cSequenceAdd(ie8->value.choice.SRBs_FailedToBeSetup_List.list, - F1AP_SRBs_FailedToBeSetup_ItemIEs_t, srbs_failedToBeSetup_item_ies); + F1AP_SRBs_FailedToBeSetup_ItemIEs_t, srbs_failedToBeSetup_item_ies); srbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_Item; srbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore; srbs_failedToBeSetup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; @@ -524,12 +533,13 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* mandatory */ /* c11. SRBs_Setup_List */ + if(resp->srbs_to_be_setup_length > 0){ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie11); ie11->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_List; ie11->criticality = F1AP_Criticality_ignore; ie11->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_Setup_List; - for (int i=0; i< req->srbs_to_be_setup_length; i++) {// + for (int i=0; i< resp->srbs_to_be_setup_length; i++) {// asn1cSequenceAdd(ie11->value.choice.SRBs_Setup_List.list, F1AP_SRBs_Setup_ItemIEs_t, srbs_setup_item_ies); srbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_Item; @@ -539,7 +549,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* ADD */ F1AP_SRBs_Setup_Item_t *srbs_setup_item=&srbs_setup_item_ies->value.choice.SRBs_Setup_Item; /* sRBID */ - srbs_setup_item->sRBID = req->srbs_to_be_setup[i].srb_id; + srbs_setup_item->sRBID = resp->srbs_to_be_setup[i].srb_id; + } } /* Optional */ @@ -581,6 +592,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup getCxt(false, instance)->default_sctp_stream_id); return 0; } + int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -658,7 +670,7 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, getCxt(false, instance)->default_sctp_stream_id); return 0; } -int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, +/*int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { @@ -667,14 +679,14 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, protocol_ctxt_t ctxt; DevAssert(pdu); container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; - /* GNB_CU_UE_F1AP_ID */ + // GNB_CU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); ctxt.rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); ctxt.instance = instance; ctxt.module_id = instance; ctxt.enb_flag = 1; - /* GNB_DU_UE_F1AP_ID */ + // GNB_DU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, @@ -694,20 +706,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, LOG_E(F1AP,"Not found rnti: %x\n", rnti); } else { for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[instance]->UE_info.active[n] == TRUE + if (RC.mac[instance]->UE_info.active[n] == true && rnti == UE_RNTI(instance, n)) { UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; break; } } } - /* We don't need the Cause */ - /* Optional RRC Container: if present, send to UE */ + + // We don't need the Cause + // Optional RRC Container: if present, send to UE F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false); if (ie && !UE_out_of_sync) { - /* RRC message and UE is reachable, send message */ + // RRC message and UE is reachable, send message const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size; mem_block_t *pdu_p = NULL; pdu_p = get_free_mem_block(sdu_len, __func__); @@ -758,8 +771,8 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rnti); if (ue_context_p && !UE_out_of_sync) { - /* UE exists and is in sync so we start a timer before releasing the - * connection */ + // UE exists and is in sync so we start a timer before releasing the + // connection pthread_mutex_lock(&rrc_release_freelist); for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { @@ -783,19 +796,198 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, pthread_mutex_unlock(&rrc_release_freelist); ue_context_p->ue_context.ue_release_timer_s1 = 0; } else if (ue_context_p && UE_out_of_sync) { - /* UE exists and is out of sync, drop the connection */ + // UE exists and is out of sync, drop the connection mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti); } else { LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti); } - /* TODO send this once the connection has really been released */ + // TODO send this once the connection has really been released + f1ap_ue_context_release_cplt_t cplt; + cplt.rnti = ctxt.rnti; + DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); + return 0; + } +}*/ + + +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_UEContextReleaseCommand_t *container; + F1AP_UEContextReleaseCommandIEs_t *ie; + protocol_ctxt_t ctxt; + + /* ITTI message to NR-RRC for the case of gNB-DU */ + MessageDef *msg_p; // message to NR-RRC + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &F1AP_UE_CONTEXT_RELEASE_CMD(msg_p); + + + DevAssert(pdu); + container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; + // GNB_CU_UE_F1AP_ID + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){ + f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + } + else{ + ctxt.rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + ctxt.instance = instance; + ctxt.module_id = instance; + ctxt.enb_flag = 1; + } + // GNB_DU_UE_F1AP_ID + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, + ie->value.choice.GNB_DU_UE_F1AP_ID); + if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){ + AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, + "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti, f1ap_ue_context_release_cmd->rnti); + } + else{ + AssertFatal(ctxt.rnti == rnti, + "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti, ctxt.rnti); + } + int UE_out_of_sync = 0; + + if(RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU){ + for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[instance]->UE_info.active[n] == true + && rnti == UE_RNTI(instance, n)) { + UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; + break; + } + } + } + + // We don't need the Cause + // Optional RRC Container: if present, send to UE + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, false); + + if (ie && !UE_out_of_sync && RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU) { + // RRC message and UE is reachable, send message + const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size; + mem_block_t *pdu_p = NULL; + pdu_p = get_free_mem_block(sdu_len, __func__); + memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len); + rlc_op_status_t rlc_status = rlc_data_req(&ctxt + , 1 + , MBMS_FLAG_NO + , 1 // SRB 1 correct? + , 0 + , 0 + , sdu_len + , pdu_p + ,NULL + ,NULL + ); + + switch (rlc_status) { + case RLC_OP_STATUS_OK: + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + break; + + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + break; + + default: + LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed " + "the order to send some data (Status Code:%d)\n", rlc_status); + break; + } + } + else if(ie && RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); + memcpy(f1ap_ue_context_release_cmd->rrc_container, + ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + } + + if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_Cause, true); + switch (ie->value.choice.Cause.present){ + case F1AP_Cause_PR_radioNetwork: + LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; + break; + case F1AP_Cause_PR_transport: + LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT; + break; + case F1AP_Cause_PR_protocol: + LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL; + break; + case F1AP_Cause_PR_misc: + LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC; + break; + default: + LOG_W(F1AP, "Unknown cause for UE context release command\n"); + break; + + } + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; + } else { + struct rrc_eNB_ue_context_s *ue_context_p; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rnti); + + if (ue_context_p && !UE_out_of_sync) { + // UE exists and is in sync so we start a timer before releasing the + // connection + pthread_mutex_lock(&rrc_release_freelist); + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) + rrc_release_info.RRC_release_ctrl[release_num].flag = 1; + else + rrc_release_info.RRC_release_ctrl[release_num].flag = 2; + + rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rnti; + LOG_D(F1AP, "add rrc_release_info RNTI %x\n", ctxt.rnti); + // TODO: how to provide the correct MUI? + rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0; + rrc_release_info.num_UEs++; + LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num, + ctxt.rnti, 0, rrc_release_info.RRC_release_ctrl[release_num].flag); + break; + } + } + + pthread_mutex_unlock(&rrc_release_freelist); + ue_context_p->ue_context.ue_release_timer_s1 = 0; + } else if (ue_context_p && UE_out_of_sync) { + // UE exists and is out of sync, drop the connection + mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti); + } else { + LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti); + } + + // TODO send this once the connection has really been released f1ap_ue_context_release_cplt_t cplt; cplt.rnti = ctxt.rnti; DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); return 0; } } + int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_cplt_t *cplt) { F1AP_F1AP_PDU_t pdu= {0}; @@ -890,10 +1082,162 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + + MessageDef *msg_p; // message to RRC + F1AP_UEContextModificationRequest_t *container; + int i; + DevAssert(pdu); + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_setup_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest; + + /* mandatory */ + /* GNB_CU_UE_F1AP_ID */ + F1AP_UEContextModificationRequestIEs_t *ieCU; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieCU, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + f1ap_ue_context_modification_req->gNB_CU_ue_id = ieCU->value.choice.GNB_CU_UE_F1AP_ID; + + /* mandatory */ + /* GNB_DU_UE_F1AP_ID */ + F1AP_UEContextModificationRequestIEs_t *ieDU_UE; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; + f1ap_ue_context_modification_req->rnti = f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_modification_req->gNB_DU_ue_id); + + if(f1ap_ue_context_modification_req->rnti<0) + LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); + else + LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); + + /* SRB */ + F1AP_UEContextModificationRequestIEs_t *ieSrb; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieSrb, container, + F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List, false); + + if(ieSrb != NULL) { + f1ap_ue_context_modification_req->srbs_to_be_setup_length = ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.count; + f1ap_ue_context_modification_req->srbs_to_be_setup = calloc(f1ap_ue_context_modification_req->srbs_to_be_setup_length, + sizeof(f1ap_srb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_req->srbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_req->srbs_to_be_setup\n"); + + for (i = 0; i < f1ap_ue_context_modification_req->srbs_to_be_setup_length; ++i) { + f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_req->srbs_to_be_setup[i]; + F1AP_SRBs_ToBeSetupMod_Item_t *srbs_tobesetupmod_item_p; + srbs_tobesetupmod_item_p = &((F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.array[i])->value.choice.SRBs_ToBeSetupMod_Item; + srb_p->srb_id = srbs_tobesetupmod_item_p->sRBID; + } + } + + /* DRB */ + F1AP_UEContextModificationRequestIEs_t *ieDrb; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDrb, container, + F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List, false); + + if(ieDrb!=NULL) { + f1ap_ue_context_modification_req->drbs_to_be_setup_length = ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.count; + f1ap_ue_context_modification_req->drbs_to_be_setup = calloc(f1ap_ue_context_modification_req->drbs_to_be_setup_length, + sizeof(f1ap_drb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_req->drbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n"); + + for (i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; ++i) { + f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_req->drbs_to_be_setup[i]; + F1AP_DRBs_ToBeSetupMod_Item_t *drbs_tobesetupmod_item_p = + &((F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.array[i])->value.choice.DRBs_ToBeSetupMod_Item; + drb_p->drb_id = drbs_tobesetupmod_item_p->dRBID; + /* TODO in the following, assume only one UP UL TNL is present. + * this matches/assumes OAI CU implementation, can be up to 2! */ + drb_p->up_ul_tnl_length = 1; + AssertFatal(drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0, + "no UL UP TNL Information in DRBs to be Setup list\n"); + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0]; + F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel; + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address); + OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); + // 3GPP assumes GTP-U is on port 2152, but OAI is configurable + drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; + + switch (drbs_tobesetupmod_item_p->rLCMode) { + case F1AP_RLCMode_rlc_am: + drb_p->rlc_mode = RLC_MODE_AM; + break; + + default: + drb_p->rlc_mode = RLC_MODE_TM; + break; + } + if (!(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU)) { + transport_layer_addr_t addr; + memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address)); + addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8; + drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT, + f1ap_ue_context_modification_req->rnti, + drb_p->drb_id, + drb_p->drb_id, + drb_p->up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p->up_ul_tnl[0].port, + lteDURecvCb, + NULL); + drb_p->up_dl_tnl_length++; + } + } + } + /* RRC Reconfiguration Complete indicator */ + F1AP_UEContextModificationRequestIEs_t *ieReconf; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieReconf, container, + F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator, false); + + if(ieReconf) { + switch(ieReconf->value.choice.RRCReconfigurationCompleteIndicator){ + case F1AP_RRCReconfigurationCompleteIndicator_true: + f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_success; + break; + + case F1AP_RRCReconfigurationCompleteIndicator_failure: + f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_failure; + break; + } + } + + /* RRCContainer */ + F1AP_UEContextModificationRequestIEs_t *ieRRC; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieRRC, container, + F1AP_ProtocolIE_ID_id_RRCContainer, false); + + if (ieRRC) { + /* correct here */ + if ( ieRRC->value.choice.RRCContainer.size ) { + f1ap_ue_context_modification_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size); + memcpy(f1ap_ue_context_modification_req->rrc_container, + ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + protocol_ctxt_t ctxt; + // decode RRC Container and act on the message type + ctxt.rnti = f1ap_ue_context_modification_req->rnti; + ctxt.instance = instance; + ctxt.module_id = instance; + ctxt.enb_flag = 1; + ctxt.eNB_index = instance; + mem_block_t *pdcp_pdu_p = get_free_mem_block(ieRRC->value.choice.RRCContainer.size, __func__); + memcpy(&pdcp_pdu_p->data[0], ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, ieRRC->value.choice.RRCContainer.size, pdcp_pdu_p); + } else { + LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n"); + } + } else { + LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; } + //void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; uint8_t *buffer=NULL; @@ -912,14 +1256,14 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); /* optional */ /* c3. ResourceCoordinationTransferContainer */ @@ -934,184 +1278,205 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { /* optional */ /* c4. DUtoCURRCInformation */ - if (0) { + if(resp->du_to_cu_rrc_information!=NULL){ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie4); ie4->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; ie4->criticality = F1AP_Criticality_reject; ie4->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation; - OCTET_STRING_fromBuf(&ie4->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + /* cellGroupConfig */ + OCTET_STRING_fromBuf(&ie4->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + } /* OPTIONAL */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie41); - ie41->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t)); - OCTET_STRING_fromBuf( ie41->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + /* measGapConfig */ + if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) { + OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig, + resp->du_to_cu_rrc_information->measGapConfig_length); + } + + /* OPTIONAL */ + /* requestedP_MaxFR1 */ + if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) { + OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1, + resp->du_to_cu_rrc_information->requestedP_MaxFR1_length); } } - /* mandatory */ - /* c5. DRBs_SetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List; - ie5->criticality = F1AP_Criticality_reject; - ie5->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, - F1AP_DRBs_SetupMod_ItemIEs_t, drbs_setupMod_item_ies); - drbs_setupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item; - drbs_setupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_setupMod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item; - /* 10.1 DRBs_SetupMod_Item */ - F1AP_DRBs_SetupMod_Item_t *drbs_setupMod_item=&drbs_setupMod_item_ies->value.choice.DRBs_SetupMod_Item; - /* dRBID */ - drbs_setupMod_item->dRBID = 30L; - /* DLTunnels_SetupMod_List */ - int maxnoofDLUPTNLInformation = 1; // 2; + /* optional */ + /* c5. DRBs_Setup_List */ + if(resp->drbs_to_be_setup_length > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List; + ie5->criticality = F1AP_Criticality_ignore; + ie5->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List; + for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, F1AP_DRBs_SetupMod_ItemIEs_t, drbs_setupmod_item_ies); + drbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item; + drbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore; + drbs_setupmod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item; + /* 7.1 DRBs_Setup_Item */ + /* ADD */ + F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item=&drbs_setupmod_item_ies->value.choice.DRBs_SetupMod_Item; + /* dRBID */ + drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; - for (int j=0; jvalue.choice.DRBs_SetupMod_List.list, - F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", - strlen("1204")); - } + for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + /* ADD */ + asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, + F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + /* gTPTunnel */ + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, + &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } // for j + } // for i } - /* mandatory */ + /* optional */ /* c6. DRBs_Modified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List; - ie6->criticality = F1AP_Criticality_reject; - ie6->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List; + if(resp->drbs_to_be_modified_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List; + ie6->criticality = F1AP_Criticality_ignore; + ie6->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie6->value.choice.DRBs_Modified_List.list, - F1AP_DRBs_Modified_ItemIEs_t, drbs_modified_item_ies); - drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item; - drbs_modified_item_ies->criticality = F1AP_Criticality_reject; - drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item; - /* 13.1 SRBs_modified_Item */ - F1AP_DRBs_Modified_Item_t *drbs_modified_item= - &drbs_modified_item_ies->value.choice.DRBs_Modified_Item; - /* dRBID */ - drbs_modified_item->dRBID = 25L; - /* ULTunnels_Modified_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; jdLUPTNLInformation_ToBeSetup_List.list, - F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item, tmp); - tmp->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", strlen("1204")); + for (int i=0; idrbs_to_be_modified_length; i++) { + asn1cSequenceAdd(ie6->value.choice.DRBs_Modified_List.list, + F1AP_DRBs_Modified_ItemIEs_t, drbs_modified_item_ies); + drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item; + drbs_modified_item_ies->criticality = F1AP_Criticality_ignore; + drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item; + /* DRBs_modified_Item */ + F1AP_DRBs_Modified_Item_t *drbs_modified_item= &drbs_modified_item_ies->value.choice.DRBs_Modified_Item; + /* dRBID */ + drbs_modified_item->dRBID = resp->drbs_to_be_modified[i].drb_id; + + /* ULTunnels_Modified_List */ + for (int j=0; jdrbs_to_be_modified[i].up_dl_tnl_length; j++) { + /* DLTunnels_Modified_Item */ + asn1cSequenceAdd(drbs_modified_item->dLUPTNLInformation_ToBeSetup_List.list, + F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item, tmp); + tmp->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } } } - /* mandatory */ + /* optional */ /* c7. SRBs_FailedToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List; - ie7->criticality = F1AP_Criticality_reject; - ie7->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List; + if(resp->srbs_failed_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie7); + ie7->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List; + ie7->criticality = F1AP_Criticality_reject; + ie7->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie7->value.choice.SRBs_FailedToBeSetupMod_List.list, - F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t, srbs_failedToBeSetupMod_item_ies); - srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item; - srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item; - /* 9.1 SRBs_FailedToBeSetupMod_Item */ - F1AP_SRBs_FailedToBeSetupMod_Item_t *srbs_failedToBeSetupMod_item= - &srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item; - /* - sRBID */ - srbs_failedToBeSetupMod_item->sRBID = 50L; - asn1cCalloc(srbs_failedToBeSetupMod_item->cause, tmp) - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + for (int i=0; isrbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie7->value.choice.SRBs_FailedToBeSetupMod_List.list, + F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t, srbs_failedToBeSetupMod_item_ies); + srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item; + srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item; + /* 9.1 SRBs_FailedToBeSetupMod_Item */ + F1AP_SRBs_FailedToBeSetupMod_Item_t *srbs_failedToBeSetupMod_item= + &srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item; + /* - sRBID */ + srbs_failedToBeSetupMod_item->sRBID = resp->srbs_failed_to_be_setup[i].rb_id; + asn1cCalloc(srbs_failedToBeSetupMod_item->cause, tmp) + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c8. DRBs_FailedToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List; - ie8->criticality = F1AP_Criticality_reject; - ie8->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List; + if(resp->drbs_failed_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie8); + ie8->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List; + ie8->criticality = F1AP_Criticality_reject; + ie8->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie8->value.choice.DRBs_FailedToBeSetupMod_List.list, - F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t, drbs_failedToBeSetupMod_item_ies); - drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item; - drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item; - /* 10.1 DRBs_ToBeSetupMod_Item */ - F1AP_DRBs_FailedToBeSetupMod_Item_t *drbs_failedToBeSetupMod_item= - &drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item; - /* dRBID */ - drbs_failedToBeSetupMod_item->dRBID = 30L; - drbs_failedToBeSetupMod_item->cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); - drbs_failedToBeSetupMod_item->cause->present = F1AP_Cause_PR_radioNetwork; - drbs_failedToBeSetupMod_item->cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + for (int i=0; idrbs_failed_to_be_setup_length; i++) { + asn1cSequenceAdd(ie8->value.choice.DRBs_FailedToBeSetupMod_List.list, + F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t, drbs_failedToBeSetupMod_item_ies); + drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item; + drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item; + /* DRBs_FailedToBeSetupMod_Item */ + F1AP_DRBs_FailedToBeSetupMod_Item_t *drbs_failedToBeSetupMod_item= + &drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item; + /* dRBID */ + drbs_failedToBeSetupMod_item->dRBID = resp->drbs_failed_to_be_setup[i].rb_id; + drbs_failedToBeSetupMod_item->cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + drbs_failedToBeSetupMod_item->cause->present = F1AP_Cause_PR_radioNetwork; + drbs_failedToBeSetupMod_item->cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c9. SCell_FailedtoSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie9); + ie9->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List; + ie9->criticality = F1AP_Criticality_ignore; + ie9->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie9->value.choice.SCell_FailedtoSetupMod_List.list, - F1AP_SCell_FailedtoSetupMod_ItemIEs_t, scell_failedtoSetupMod_item_ies); - scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item; - scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item; - /* 8.1 SCell_ToBeSetup_Item */ - F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; - /* - sCell_ID */ - addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &f1ap_req(false, instance)->cell[i]); - asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + for (int i=0; i<1; i++) { + asn1cSequenceAdd(ie9->value.choice.SCell_FailedtoSetupMod_List.list, + F1AP_SCell_FailedtoSetupMod_ItemIEs_t, scell_failedtoSetupMod_item_ies); + scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item; + scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item; + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; + /* - sCell_ID */ + addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &f1ap_req(false, instance)->cell[i]); + asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c10. DRBs_FailedToBeModified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List; - ie10->criticality = F1AP_Criticality_reject; - ie10->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie10); + ie10->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List; + ie10->criticality = F1AP_Criticality_reject; + ie10->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie10->value.choice.DRBs_FailedToBeModified_List.list, - F1AP_DRBs_FailedToBeModified_ItemIEs_t, drbs_failedToBeModified_item_ies); - drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item; - drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject; - drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item; - /* 13.1 DRBs_FailedToBeModified_Item */ - F1AP_DRBs_FailedToBeModified_Item_t *drbs_failedToBeModified_item= - &drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item ; - /* dRBID */ - drbs_failedToBeModified_item->dRBID = 30L; - asn1cCalloc(drbs_failedToBeModified_item->cause, tmp); - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + for (int i=0; i<1; i++) { + asn1cSequenceAdd(ie10->value.choice.DRBs_FailedToBeModified_List.list, + F1AP_DRBs_FailedToBeModified_ItemIEs_t, drbs_failedToBeModified_item_ies); + drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item; + drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item; + /* 13.1 DRBs_FailedToBeModified_Item */ + F1AP_DRBs_FailedToBeModified_Item_t *drbs_failedToBeModified_item= + &drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item ; + /* dRBID */ + drbs_failedToBeModified_item->dRBID = 30L; + asn1cCalloc(drbs_failedToBeModified_item->cause, tmp); + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } // /* */ @@ -1162,6 +1527,28 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { } } } + /* optional */ + /* c12. SRBs_Setup_List */ + if(resp->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List; + ie12->criticality = F1AP_Criticality_ignore; + ie12->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_SetupMod_List; + + for (int i=0; i< resp->srbs_to_be_setup_length; i++) {// + asn1cSequenceAdd(ie12->value.choice.SRBs_SetupMod_List.list, + F1AP_SRBs_SetupMod_ItemIEs_t, srbs_setupmod_item_ies); + srbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_Item; + srbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_setupmod_item_ies->value.present = F1AP_SRBs_SetupMod_ItemIEs__value_PR_SRBs_SetupMod_Item; + /* 11.1 SRBs_Setup_Item */ + /* ADD */ + F1AP_SRBs_SetupMod_Item_t *srbs_setupmod_item=&srbs_setupmod_item_ies->value.choice.SRBs_SetupMod_Item; + /* sRBID */ + srbs_setupmod_item->sRBID = resp->srbs_to_be_setup[i].srb_id; + srbs_setupmod_item->lCID = resp->srbs_to_be_setup[i].srb_id; + } + } /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -1169,9 +1556,10 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { return -1; } - //f1ap_itti_send_sctp_data_req(false, instance, buffer, len, 0); + f1ap_itti_send_sctp_data_req(false, instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id); return 0; } + int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { AssertFatal(1==0,"Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index 82643fa933..acf74f69d7 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -74,7 +74,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp); int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); diff --git a/openair2/F1AP/f1ap_encoder.c b/openair2/F1AP/f1ap_encoder.c index e623e66536..b249f23cfe 100644 --- a/openair2/F1AP/f1ap_encoder.c +++ b/openair2/F1AP/f1ap_encoder.c @@ -33,7 +33,7 @@ #include "f1ap_common.h" #include "f1ap_encoder.h" -int asn1_encoder_xer_print = 1; +int asn1_encoder_xer_print = 0; int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) { ssize_t encoded; diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index fec03bb0b9..0812a976f6 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -50,7 +50,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = { { DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE }, /* gNBCUConfigurationUpdate */ { DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */ { DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */ - { 0, 0, 0 }, /* UEContextModification */ + { DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0 }, /* UEContextModification */ { 0, 0, 0 }, /* UEContextModificationRequired */ { 0, 0, 0 }, /* UEMobilityCommand */ { CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */ diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index 21096a6518..e45edcc3a3 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -32,7 +32,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; sctp_data_req->stream = stream; - LOG_I(F1AP, "Sending ITTI message to SCTP Task\n"); + LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index a7bc3e8545..0a50d19e13 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -58,6 +58,7 @@ #define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity" #define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10" #define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10" +#define CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD "ul_prbblack_SNR_threshold" #define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres" #define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres" #define CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER "dl_bler_target_upper" @@ -66,7 +67,8 @@ #define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper" #define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower" #define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs" -#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max" +#define CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX "dl_harq_round_max" +#define CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX "ul_harq_round_max" #define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb" #define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs" @@ -96,6 +98,7 @@ {CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \ @@ -104,9 +107,10 @@ {CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \ -{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ +{CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, "Maximum number of DL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ +{CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, "Maximum number of UL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \ -{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \ +{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -128,17 +132,55 @@ #define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17 #define MACRLC_PUSCHTARGETSNRX10_IDX 18 #define MACRLC_PUCCHTARGETSNRX10_IDX 19 -#define MACRLC_PUCCHFAILURETHRES_IDX 20 -#define MACRLC_PUSCHFAILURETHRES_IDX 21 -#define MACRLC_DL_BLER_TARGET_UPPER_IDX 22 -#define MACRLC_DL_BLER_TARGET_LOWER_IDX 23 -#define MACRLC_DL_MAX_MCS_IDX 24 -#define MACRLC_UL_BLER_TARGET_UPPER_IDX 25 -#define MACRLC_UL_BLER_TARGET_LOWER_IDX 26 -#define MACRLC_UL_MAX_MCS_IDX 27 -#define MACRLC_HARQ_ROUND_MAX_IDX 28 -#define MACRLC_MIN_GRANT_PRB_IDX 29 -#define MACRLC_MIN_GRANT_MCS_IDX 30 +#define MACRLC_UL_PRBBLACK_SNR_THRESHOLD_IDX 20 +#define MACRLC_PUCCHFAILURETHRES_IDX 21 +#define MACRLC_PUSCHFAILURETHRES_IDX 22 +#define MACRLC_DL_BLER_TARGET_UPPER_IDX 23 +#define MACRLC_DL_BLER_TARGET_LOWER_IDX 24 +#define MACRLC_DL_MAX_MCS_IDX 25 +#define MACRLC_UL_BLER_TARGET_UPPER_IDX 26 +#define MACRLC_UL_BLER_TARGET_LOWER_IDX 27 +#define MACRLC_UL_MAX_MCS_IDX 28 +#define MACRLC_DL_HARQ_ROUND_MAX_IDX 29 +#define MACRLC_UL_HARQ_ROUND_MAX_IDX 30 +#define MACRLC_MIN_GRANT_PRB_IDX 31 +#define MACRLC_MIN_GRANT_MCS_IDX 32 + +#define MACRLCPARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s2 = { config_check_intrange, {1, 8} } }, /* DL max HARQ rounds */ \ + { .s2 = { config_check_intrange, {1, 8} } }, /* UL max HARQ rounds */ \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 21655a74d5..f8a4e495a8 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -85,7 +85,8 @@ extern uint16_t sf_ahead; int macrlc_has_f1 = 0; -extern ngran_node_t node_type; + +static ngran_node_t get_node_type(void); extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint32_t frame_type); @@ -758,8 +759,6 @@ void RCconfig_NR_L1(void) { LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_CC[0]=%d for init_gNB_afterRU()\n", __FUNCTION__, RC.nb_nr_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_macrlc_inst:%d because used by mac_top_init_gNB()\n", __FUNCTION__, RC.nb_nr_macrlc_inst); - mac_top_init_gNB(); - configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, @@ -795,6 +794,7 @@ void RCconfig_nr_macrlc() { paramdef_t GNBParams[] = GNBPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; + ngran_node_t node_type = get_node_type(); config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; @@ -816,18 +816,23 @@ void RCconfig_nr_macrlc() { } paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_MacRLCParams [] = MACRLCPARAMS_CHECK; + for (int i = 0; i < sizeof(MacRLC_Params) / sizeof(paramdef_t); ++i) + MacRLC_Params[i].chkPptr = &(config_check_MacRLCParams[i]); config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst=MacRLC_ParamList.numelt; - mac_top_init_gNB(); + mac_top_init_gNB(node_type); RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (j=0;jpusch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHTARGETSNRX10_IDX].iptr); RC.nrmac[j]->pucch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHTARGETSNRX10_IDX].iptr); + RC.nrmac[j]->ul_prbblack_SNR_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_PRBBLACK_SNR_THRESHOLD_IDX].iptr); RC.nrmac[j]->pucch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHFAILURETHRES_IDX].iptr); RC.nrmac[j]->pusch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHFAILURETHRES_IDX].iptr); @@ -886,11 +891,12 @@ void RCconfig_nr_macrlc() { dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr); + dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler; ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr); ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr); ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr); - RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr); + ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr); RC.nrmac[j]->num_ulprbbl = num_prbbl; @@ -1235,8 +1241,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { (NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d", NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l]); } - LOG_I(GNB_APP,"SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr); - NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr; LOG_I(GNB_APP,"pdsch_AntennaPorts N1 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N1 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr; LOG_I(GNB_APP,"pdsch_AntennaPorts N2 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr); @@ -1957,9 +1961,38 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { f1Setup->measurement_timing_information[k] = "0"; f1Setup->ranac[k] = 0; f1Setup->mib[k] = rrc->carrier.MIB; - f1Setup->sib1[k] = rrc->carrier.SIB1; f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB; - f1Setup->sib1_length[k] = rrc->carrier.sizeof_SIB1; + + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; + + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)rrc->carrier.SIB1, + rrc->carrier.sizeof_SIB1); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"SIB1 decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, bcch_message, 1 ); + exit(1); + } + + NR_SIB1_t *bcch_SIB1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + f1Setup->sib1[k] = calloc(1,rrc->carrier.sizeof_SIB1); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, + NULL, + (void *)bcch_SIB1, + f1Setup->sib1[k], + NR_MAX_SIB_LENGTH/8); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + LOG_I(NR_RRC, "SIB1 container to be integrated in F1 Setup request:\n"); + xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1 ); + //} + f1Setup->sib1_length[k] = (enc_rval.encoded+7)/8; break; } } @@ -2121,7 +2154,6 @@ void configure_gnb_du_mac(int inst) { // LOG_I(GNB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n", inst, &carrier->sib2->radioResourceConfigCommon); LOG_I(GNB_APP,"Configuring gNB DU MAC/L1 %d \n", inst); rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -2227,8 +2259,8 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up return(ret); } -void set_node_type(void) { - int j; +static ngran_node_t get_node_type(void) +{ paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; paramdef_t GNBParams[] = GNBPARAMS_DESC; @@ -2239,24 +2271,19 @@ void set_node_type(void) { if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; - for (j=0;jUE_sched_ctrl[UE_id]); - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error + UE_scheduling_control->cdrx_configured = false; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { @@ -1119,9 +1119,9 @@ void eNB_Config_Local_DRX(instance_t Mod_id, } /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when receiving RRC Reconfiguration Complete - UE_scheduling_control->cdrx_waiting_ack = TRUE; // waiting for RRC Reconfiguration Complete message - UE_scheduling_control->in_active_time = FALSE; + UE_scheduling_control->cdrx_configured = false; // will be set to true when receiving RRC Reconfiguration Complete + UE_scheduling_control->cdrx_waiting_ack = true; // waiting for RRC Reconfiguration Complete message + UE_scheduling_control->in_active_time = false; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; @@ -1297,13 +1297,13 @@ void eNB_Config_Local_DRX(instance_t Mod_id, } if (choiceSetup->shortDRX == NULL) { - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; UE_scheduling_control->drx_shortCycle_timer = 0; UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; switch (choiceSetup->shortDRX->shortDRX_Cycle) { @@ -1380,7 +1380,7 @@ void eNB_Config_Local_DRX(instance_t Mod_id, UE_scheduling_control->drx_shortCycle_timer_thres = UE_scheduling_control->drx_shortCycle_timer_value * UE_scheduling_control->short_drx_cycle_duration; } - UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = false; UE_scheduling_control->drx_longCycle_timer = 0; switch (choiceSetup->longDRX_CycleStartOffset.present) { diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index d4945f0182..abe780741c 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -243,7 +243,6 @@ typedef struct { // -1:No UE in list int tail; int num_UEs; - //boolean_t active[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; } UE_list_NB_IoT_t; @@ -403,7 +402,7 @@ typedef struct schedule_result{ // pointer to DCI void *DCI_pdu; // when all the procedure related to this DCI, enable this flag - boolean_t DCI_release; + bool DCI_release; // Indicate the channel which to transmit channel_NB_IoT_t channel; // rnti @@ -452,7 +451,7 @@ typedef enum ce_level_e{ /*! \brief eNB template for the Random access information */ typedef struct RA_TEMPLATE_NB_IoT_s{ - boolean_t active; + bool active; uint32_t msg3_retransmit_count; uint32_t msg4_retransmit_count; uint16_t ta; @@ -461,8 +460,8 @@ typedef struct RA_TEMPLATE_NB_IoT_s{ rnti_t ue_rnti; rnti_t ra_rnti; struct RA_TEMPLATE_NB_IoT_s *next, *prev; - boolean_t wait_msg4_ack; - boolean_t wait_msg3_ack; + bool wait_msg4_ack; + bool wait_msg3_ack; uint8_t rar_buffer[7]; } RA_TEMPLATE_NB_IoT; @@ -530,7 +529,7 @@ typedef struct { uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ - boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ + bool head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ } mac_rlc_status_resp_NB_IoT_t; // global variables diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index d647eff7cb..53ab98a33f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -135,7 +135,7 @@ void schedule_SRS(module_id_t module_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); /* Test if Active Time not running since 6+ subframes */ - if (UE_scheduling_control->cdrx_configured == TRUE && UE_scheduling_control->in_active_time == FALSE) { + if (UE_scheduling_control->cdrx_configured == true && UE_scheduling_control->in_active_time == false) { /* * TODO: 6+ subframes condition not checked here */ @@ -204,7 +204,7 @@ void schedule_CSI(module_id_t module_idP, cc = &eNB->common_channels[CC_id]; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -223,9 +223,9 @@ void schedule_CSI(module_id_t module_idP, */ UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Test if CQI masking activated */ - if (UE_scheduling_control->cqi_mask_boolean == TRUE) { + if (UE_scheduling_control->cqi_mask_boolean == true) { // CQI masking => test if onDurationTime not running since 6+ subframe if (UE_scheduling_control->on_duration_timer == 0) { /* @@ -234,7 +234,7 @@ void schedule_CSI(module_id_t module_idP, continue; } } else { // No CQI masking => test if Active Time not running since 6+ subframe - if (UE_scheduling_control->in_active_time == FALSE) { + if (UE_scheduling_control->in_active_time == false) { /* * TODO: 6+ subframes condition not checked here */ @@ -677,8 +677,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Set and increment CDRX related timers */ - if (UE_scheduling_control->cdrx_configured == TRUE) { - boolean_t harq_active_time_condition = FALSE; + if (UE_scheduling_control->cdrx_configured == true) { + bool harq_active_time_condition = false; UE_TEMPLATE *UE_template = NULL; unsigned long active_time_condition = 0; // variable used only for tracing purpose @@ -721,7 +721,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id]++; if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 5) { - harq_active_time_condition = TRUE; + harq_active_time_condition = true; UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] = 0; active_time_condition = 5; // for tracing purpose } @@ -747,24 +747,24 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* When timer expires switch into short or long DRX cycle */ if (UE_scheduling_control->drx_shortCycle_timer_thres > 0) { - UE_scheduling_control->in_short_drx_cycle = TRUE; + UE_scheduling_control->in_short_drx_cycle = true; UE_scheduling_control->drx_shortCycle_timer = 0; - UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = false; } else { - UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->in_long_drx_cycle = true; } } } /* Short DRX Cycle */ - if (UE_scheduling_control->in_short_drx_cycle == TRUE) { + if (UE_scheduling_control->in_short_drx_cycle == true) { UE_scheduling_control->drx_shortCycle_timer++; /* When the Short DRX cycles are over, switch to long DRX cycle */ if (UE_scheduling_control->drx_shortCycle_timer > UE_scheduling_control->drx_shortCycle_timer_thres) { UE_scheduling_control->drx_shortCycle_timer = 0; - UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->in_short_drx_cycle = false; + UE_scheduling_control->in_long_drx_cycle = true; UE_scheduling_control->drx_longCycle_timer = 0; } } else { @@ -772,7 +772,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Long DRX Cycle */ - if (UE_scheduling_control->in_long_drx_cycle == TRUE) { + if (UE_scheduling_control->in_long_drx_cycle == true) { UE_scheduling_control->drx_longCycle_timer++; if (UE_scheduling_control->drx_longCycle_timer > UE_scheduling_control->drx_longCycle_timer_thres) { @@ -783,18 +783,18 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Check for error cases */ - if ((UE_scheduling_control->in_short_drx_cycle == TRUE) && (UE_scheduling_control->in_long_drx_cycle == TRUE)) { + if ((UE_scheduling_control->in_short_drx_cycle == true) && (UE_scheduling_control->in_long_drx_cycle == true)) { LOG_E(MAC, "Error in C-DRX: UE id %d is in both short and long DRX cycle. Should not happen. Back it to long cycle only\n", UE_id); - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; } /* Condition to start On Duration Timer */ - if (UE_scheduling_control->in_short_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (UE_scheduling_control->in_short_drx_cycle == true && UE_scheduling_control->on_duration_timer == 0) { if (((frameP * 10) + subframeP) % (UE_scheduling_control->short_drx_cycle_duration) == (UE_scheduling_control->drx_start_offset) % (UE_scheduling_control->short_drx_cycle_duration)) { UE_scheduling_control->on_duration_timer = 1; } - } else if (UE_scheduling_control->in_long_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + } else if (UE_scheduling_control->in_long_drx_cycle == true && UE_scheduling_control->on_duration_timer == 0) { if (((frameP * 10) + subframeP) % (UE_scheduling_control->drx_longCycle_timer_thres) == (UE_scheduling_control->drx_start_offset)) { UE_scheduling_control->on_duration_timer = 1; @@ -811,7 +811,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* (a)synchronous HARQ processes handling for Active Time */ for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { - harq_active_time_condition = TRUE; + harq_active_time_condition = true; active_time_condition = 2; // for tracing purpose break; } @@ -822,9 +822,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control->drx_inactivity_timer > 1 || harq_active_time_condition || UE_template->ul_SR > 0) { - UE_scheduling_control->in_active_time = TRUE; + UE_scheduling_control->in_active_time = true; } else { - UE_scheduling_control->in_active_time = FALSE; + UE_scheduling_control->in_active_time = false; } /* BEGIN VCD */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index e5b95a7f47..c659df8d31 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1225,7 +1225,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); - mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; + mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = true; mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels; cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 596d978a98..0898622115 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -2075,7 +2075,7 @@ schedule_PCH(module_id_t module_idP, for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { ue_pf_po = &UE_PF_PO[CC_id][i]; - if (ue_pf_po->enable_flag != TRUE) { + if (ue_pf_po->enable_flag != true) { continue; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 6c9ffabd4f..9836b643d4 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -69,7 +69,7 @@ int last_ulsch_ue_id_volte[MAX_NUM_CCs] = {-1}; uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint8_t dlsch_ue_select_tbl_in_use; uint8_t new_dlsch_ue_select_tbl_in_use; - boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; + bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif @@ -125,7 +125,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, UE_info_t *UE_info = &RC.mac[module_idP]->UE_info; for (UE_id = 0; UE_id DL_req[CC_id].dl_config_request_body; for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -331,7 +331,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( break; } - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -459,7 +459,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( break; } - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -607,7 +607,7 @@ static void dlsch_scheduler_pre_processor_reset_fairRR( if (rnti == NOT_A_RNTI) continue; - if (UE_info->active[UE_id] != TRUE) + if (UE_info->active[UE_id] != true) continue; LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); @@ -755,7 +755,7 @@ static void assign_rbs_required_fairRR( // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] != TRUE) + if (UE_info->active[UE_id] != true) continue; pCCid = UE_PCCID(Mod_id, UE_id); @@ -945,7 +945,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_info->active[i] != TRUE) + if (UE_info->active[i] != true) continue; UE_id = i; @@ -2241,7 +2241,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( // UE round >0 for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { - if (UE_info->active[UE_id] == FALSE) + if (UE_info->active[UE_id] == false) continue; rnti = UE_RNTI(module_idP,UE_id); @@ -2251,7 +2251,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( CC_id = UE_PCCID(module_idP,UE_id); - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) + if (UE_info->UE_template[CC_id][UE_id].configured == false) continue; if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0 @@ -2401,7 +2401,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( } for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { - if (UE_info->active[UE_id] == FALSE) + if (UE_info->active[UE_id] == false) continue; rnti = UE_RNTI(module_idP,UE_id); @@ -2414,7 +2414,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( if (UE_id > last_ulsch_ue_id[CC_id]) continue; - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) + if (UE_info->UE_template[CC_id][UE_id].configured == false) continue; if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0 diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index d53e0cadd3..58abbd7a47 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1989,7 +1989,7 @@ find_UE_id(module_id_t mod_idP, return -1; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] == TRUE) { + if (UE_info->active[UE_id] == true) { int CC_id = UE_PCCID(mod_idP, UE_id); if (CC_id>=0 && CC_idUE_template[CC_id][UE_id].rnti == rntiP) { return UE_id; @@ -2063,7 +2063,7 @@ UE_RNTI(module_id_t mod_idP, } //------------------------------------------------------------------------------ -boolean_t +bool is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ @@ -2187,20 +2187,20 @@ add_new_ue(module_id_t mod_idP, UE_info->num_UEs); for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_info->active[i] == TRUE) + if (UE_info->active[i] == true) continue; UE_id = i; memset(&UE_info->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE)); UE_info->UE_template[cc_idP][UE_id].rnti = rntiP; - UE_info->UE_template[cc_idP][UE_id].configured = FALSE; + UE_info->UE_template[cc_idP][UE_id].configured = false; UE_info->numactiveCCs[UE_id] = 1; UE_info->numactiveULCCs[UE_id] = 1; UE_info->pCC_id[UE_id] = cc_idP; UE_info->ordered_CCids[0][UE_id] = cc_idP; UE_info->ordered_ULCCids[0][UE_id] = cc_idP; UE_info->num_UEs++; - UE_info->active[UE_id] = TRUE; + UE_info->active[UE_id] = true; add_ue_list(&UE_info->list, UE_id); dump_ue_list(&UE_info->list); pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; @@ -2280,7 +2280,7 @@ rrc_mac_remove_ue(module_id_t mod_idP, UE_id, pCC_id, rntiP); - UE_info->active[UE_id] = FALSE; + UE_info->active[UE_id] = false; UE_info->num_UEs--; remove_ue_list(&UE_info->list, UE_id); @@ -2366,22 +2366,6 @@ rrc_mac_remove_ue(module_id_t mod_idP, return 0; } -//------------------------------------------------------------------------------ -/* - * Returns the previous UE_id in the scheduling list in UL or DL - */ -inline int prev(UE_list_t *listP, int nodeP) { - if (nodeP == listP->head) - return -1; /* there is no previous of the head */ - - for (int j = listP->head; j >= 0; j = listP->next[j]) - if (listP->next[j] == nodeP) - return j; - - LOG_E(MAC, "%s(): could not find previous to %d in UE_list\n", __func__, nodeP); - dump_ue_list(listP); - return -1; -} // This has to be updated to include BSR information //------------------------------------------------------------------------------ @@ -3488,7 +3472,7 @@ has_ul_grant(module_id_t module_idP, } //------------------------------------------------------------------------------ -boolean_t +bool CCE_allocation_infeasible(int module_idP, int CC_idP, int format_flag, @@ -3501,7 +3485,7 @@ CCE_allocation_infeasible(int module_idP, nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; - boolean_t res = TRUE; + bool res = true; if (format_flag != 2) { // DL DCI if (DL_req->number_pdu == MAX_NUM_DL_PDU) { @@ -3517,7 +3501,7 @@ CCE_allocation_infeasible(int module_idP, subframe, format_flag, rnti, aggregation); if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) - res = FALSE; + res = false; DL_req->number_pdu--; } @@ -3532,7 +3516,7 @@ CCE_allocation_infeasible(int module_idP, HI_DCI0_req->number_of_dci++; if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) - res = FALSE; + res = false; HI_DCI0_req->number_of_dci--; } @@ -5029,7 +5013,7 @@ SR_indication(module_id_t mod_idP, if (UE_id != -1) { UE_scheduling_ctrl = &(UE_info->UE_sched_ctrl[UE_id]); - if ((UE_scheduling_ctrl->cdrx_configured == TRUE) && + if ((UE_scheduling_ctrl->cdrx_configured == true) && (UE_scheduling_ctrl->dci0_ongoing_timer > 0) && (UE_scheduling_ctrl->dci0_ongoing_timer < 8)) { LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d. \ @@ -5052,7 +5036,7 @@ SR_indication(module_id_t mod_idP, } UE_info->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_info->UE_template[cc_idP][UE_id].ul_active = TRUE; + UE_info->UE_template[cc_idP][UE_id].ul_active = true; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index d4f486f761..f9218d8511 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -242,7 +242,7 @@ rx_sdu(const module_id_t enb_mod_idP, } /* CDRX UL HARQ timers */ - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; /* @@ -329,17 +329,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { // Release RNTI of LTE PHY when RA does not succeed - UE_free_list_t *free_list = NULL; - pthread_mutex_lock(&lock_ue_freelist); - free_list = &mac->UE_free_list; - free_list->UE_free_ctrl[free_list->tail_freelist].rnti = current_rnti; - free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = 1; - free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 1; - free_list->num_UEs++; - mac->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[mac->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = current_rnti; - mac->UE_release_req.ue_release_request_body.number_of_TLVs++; - free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); - pthread_mutex_unlock(&lock_ue_freelist); + put_UE_in_freelist(enb_mod_idP, current_rnti, true); cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); nfapi_hi_dci0_request_t *hi_dci0_req = NULL; @@ -1003,7 +993,7 @@ rx_sdu(const module_id_t enb_mod_idP, /* CDRX UL HARQ timers */ if (UE_id != -1) { - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; /* @@ -1447,7 +1437,7 @@ schedule_ulsch_rnti(module_id_t module_idP, continue; // don't schedule if Msg5 is not received yet - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) { + if (UE_info->UE_template[CC_id][UE_id].configured == false) { LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping " "UE scheduling \n", @@ -2033,7 +2023,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, } /* Don't schedule if Msg4 is not received yet */ - if (UE_template->configured == FALSE) { + if (UE_template->configured == false) { LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n", module_idP, frameP, diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 6637d05a8a..1fd7182c6f 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -811,9 +811,9 @@ typedef struct { /// TBS from last UL scheduling int TBS_UL[8]; /// Flag to indicate UL has been scheduled at least once - boolean_t ul_active; + bool ul_active; /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) - boolean_t configured; + bool configured; /// MCS from last scheduling uint8_t mcs[8]; @@ -1026,16 +1026,16 @@ typedef struct { /* C-DRX related timers */ /* Note: only valid for FDD and LTE UE when this comment is written (11-01-19)*/ - /// is TRUE if the cqi mask feature is activated by RRC configuration - boolean_t cqi_mask_boolean; - /// is TRUE if the following drx parameters are configured for UE - boolean_t cdrx_configured; + /// is true if the cqi mask feature is activated by RRC configuration + bool cqi_mask_boolean; + /// is true if the following drx parameters are configured for UE + bool cdrx_configured; /* - * if TRUE, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge + * if true, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge * the activation. This is needed, during the RRC configuration process, when the context is * configured on the eNB side, but not yet on the UE side... */ - boolean_t cdrx_waiting_ack; + bool cdrx_waiting_ack; /* * Is set when a ULSCH scheduling is done and run until the first corresponding transmission is done (4 subframes). * When set, SR cannot be set for the UE. This allows OAI to avoid concidering a SR as uncompleted if the UE sends @@ -1043,16 +1043,16 @@ typedef struct { * create a lost in timers synchronization. */ uint8_t dci0_ongoing_timer; - /// is TRUE if the UE is in "Active Time", hence listening to PDCCH - boolean_t in_active_time; + /// is true if the UE is in "Active Time", hence listening to PDCCH + bool in_active_time; /// OnDurationTimer uint16_t on_duration_timer; uint16_t on_duration_timer_thres; /// drx-InactivityTimer uint16_t drx_inactivity_timer; uint16_t drx_inactivity_timer_thres; - /// is TRUE if UE is currently in short DRX cycle - boolean_t in_short_drx_cycle; + /// is true if UE is currently in short DRX cycle + bool in_short_drx_cycle; /// drxShortCycleTimer int (1..16) (number of short DRX cycles duration before long DRX cycles) uint8_t drx_shortCycle_timer_value; /// shortDRX-Cycle (duration of one short DRX cycle) @@ -1060,8 +1060,8 @@ typedef struct { /// DRX short cycle timer before switching to long DRX cycle = drx_shortCycle_timer_value * short_drx_cycle_duration uint16_t drx_shortCycle_timer; uint16_t drx_shortCycle_timer_thres; - /// is TRUE if UE is currently in long DRX cycle - boolean_t in_long_drx_cycle; + /// is true if UE is currently in long DRX cycle + bool in_long_drx_cycle; /// longDRX-CycleStartOffset (long DRX cycle timer) uint16_t drx_longCycle_timer; uint16_t drx_longCycle_timer_thres; @@ -1183,7 +1183,7 @@ typedef struct { UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_ENB]; UE_list_t list; int num_UEs; - boolean_t active[MAX_MOBILES_PER_ENB]; + bool active[MAX_MOBILES_PER_ENB]; } UE_info_t; /*! \brief deleting control information*/ @@ -1191,18 +1191,10 @@ typedef struct { ///rnti of UE rnti_t rnti; ///remove UE context flag - boolean_t removeContextFlg; + bool removeContextFlg; ///remove RA flag - boolean_t raFlag; + bool raFlag; } UE_free_ctrl_t; -/*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/ -typedef struct { - /// deleting control info - UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1]; - int num_UEs; - int head_freelist; ///the head position of the delete list - int tail_freelist; ///the tail position of the delete list -} UE_free_list_t; /** * describes contiguous RBs @@ -1443,7 +1435,7 @@ typedef struct eNB_MAC_INST_s { /// processing time of eNB PCH scheduler time_stats_t schedule_pch; - UE_free_list_t UE_free_list; + UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1]; /// for scheduling selection SCHEDULER_MODES scheduler_mode; /// Default scheduler: Pre-processor implementation. Algorithms for UL/DL diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index 522dc2721f..212422898b 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -71,7 +71,7 @@ extern rb_id_t mbms_rab_id; extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern uint8_t dlsch_ue_select_tbl_in_use; extern uint8_t new_dlsch_ue_select_tbl_in_use; -extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; +extern bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index b92ce85608..889c727fdd 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -400,7 +400,7 @@ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); rnti_t UE_RNTI(module_id_t module_idP, int UE_id); int UE_PCCID(module_id_t module_idP, int UE_id); uint8_t find_active_UEs(module_id_t module_idP); -boolean_t is_UE_active(module_id_t module_idP, int UE_id); +bool is_UE_active(module_id_t module_idP, int UE_id); uint8_t get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt); int8_t find_active_UEs_with_traffic(module_id_t module_idP); @@ -416,11 +416,11 @@ int get_nCCE_offset(int *CCE_table, int allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_only); -boolean_t CCE_allocation_infeasible(int module_idP, - int CC_idP, - int common_flag, - int subframe, - int aggregation, int rnti); +bool CCE_allocation_infeasible(int module_idP, + int CC_idP, + int common_flag, + int subframe, + int aggregation, int rnti); /* tries to allocate a CCE. If it succeeds, reserves NFAPI DCI and DLSCH config */ int CCE_try_allocate_dlsch(int module_id, int CC_id, @@ -741,13 +741,12 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len); */ BSR_LONG *get_bsr_long(module_id_t module_idP, uint8_t bsr_len); -/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP) +/*! \fn bool update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP) \brief get the rlc stats and update the bsr level for each lcid \param[in] Mod_id instance of the UE \param[in] frame Frame index */ -boolean_t update_bsr(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP, eNB_index_t eNB_index); +bool update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, eNB_index_t eNB_index); /*! \fn locate_BsrIndexByBufferSize (int *table, int size, int value) \brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index bb969668d6..db4d51a92f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -638,7 +638,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, LOG_E(MAC, "UE %d has RNTI NOT_A_RNTI!\n", UE_id); continue; } - if (UE_info->active[UE_id] != TRUE) { + if (UE_info->active[UE_id] != true) { LOG_E(MAC, "UE %d RNTI %x is NOT active!\n", UE_id, rnti); continue; } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 926c44381c..d7796d1d40 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2325,8 +2325,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; uint8_t lcid = 0, lcid_rlc_pdu_count = 0; - boolean_t is_lcid_processed = FALSE; - boolean_t is_all_lcid_processed = FALSE; + bool is_lcid_processed = false; + bool is_all_lcid_processed = false; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t payload_offset = 0, num_sdus = 0; @@ -2444,11 +2444,11 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization for (lcid = DCCH; - (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) { + (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == false); lcid++) { if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) { lcid_rlc_pdu_count = 0; - is_lcid_processed = FALSE; + is_lcid_processed = false; lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP, UE_mac_inst[module_idP]. @@ -2536,8 +2536,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, //No more remaining TBS after this PDU //exit the function rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; + is_lcid_processed = true; + is_all_lcid_processed = true; } else { rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128) ? 3 : 2; @@ -2547,8 +2547,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) { rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; + is_lcid_processed = true; + is_all_lcid_processed = true; } } @@ -2559,7 +2559,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, lcid_rlc_pdu_count++; } else { /* avoid infinite loop ... */ - is_lcid_processed = TRUE; + is_lcid_processed = true; } /* Get updated BO after multiplexing this PDU */ @@ -3164,7 +3164,7 @@ ue_scheduler(const module_id_t module_idP, } //Check whether Regular BSR is triggered - if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == TRUE) { + if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == true) { // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures // outlined in Sections 5.4.4 an 5.4.5 of 36.321 UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; @@ -3251,11 +3251,11 @@ ue_scheduler(const module_id_t module_idP, // to be improved -boolean_t +bool update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, eNB_index_t eNB_index) { mac_rlc_status_resp_t rlc_status; - boolean_t bsr_regular_triggered = FALSE; + bool bsr_regular_triggered = false; uint8_t lcid; uint8_t lcgid; uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined @@ -3352,7 +3352,7 @@ update_bsr(module_id_t module_idP, frame_t frameP, (lcgid_buffer_remain [UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; LOG_D(MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n", module_idP, lcid, @@ -3364,7 +3364,7 @@ update_bsr(module_id_t module_idP, frame_t frameP, // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; if ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_REGULAR) == 0) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 9123afd324..58e435f3f1 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -39,6 +39,7 @@ #include #include "NR_SubcarrierSpacing.h" +#include "NR_CSI-ReportConfig.h" #include "openair1/SCHED_NR_UE/harq_nr.h" #define NR_SHORT_BSR_TABLE_SIZE 32 @@ -63,6 +64,7 @@ #define CCCH_PAYLOAD_SIZE_MAX 512 #define RAR_PAYLOAD_SIZE_MAX 128 #define MAX_BWP_SIZE 275 +#define MAX_CSI_REPORTCONFIG 48 typedef enum frequency_range_e { FR1 = 0, @@ -512,5 +514,37 @@ typedef struct Type0_PDCCH_CSS_config_s { bool active; } NR_Type0_PDCCH_CSS_config_t; +typedef struct { + uint8_t nb_ssbri_cri; + uint8_t cri_ssbri_bitlen; + uint8_t rsrp_bitlen; + uint8_t diff_rsrp_bitlen; +} L1_RSRP_bitlen_t; + +typedef struct{ + uint8_t ri_restriction; + uint8_t cri_bitlen; + uint8_t ri_bitlen; + uint8_t li_bitlen[8]; + uint8_t pmi_x1_bitlen[8]; + uint8_t pmi_x2_bitlen[8]; + uint8_t cqi_bitlen[8]; +} CSI_Meas_bitlen_t; + +typedef struct nr_csi_report { + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + long periodicity; + uint16_t offset; + long ** SSB_Index_list; + long ** CSI_Index_list; +// uint8_t nb_of_nzp_csi_report; + uint8_t nb_of_csi_ssb_report; + L1_RSRP_bitlen_t CSI_report_bitlen; + CSI_Meas_bitlen_t csi_meas_bitlen; + int codebook_mode; + int N1; + int N2; +} nr_csi_report_t; + #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 5d6f9a2f2e..1855958879 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4128,22 +4128,22 @@ uint16_t compute_pucch_prb_size(uint8_t format, } } -int get_bw_tbslbrm(NR_BWP_t *genericParameters, +int get_bw_tbslbrm(int scc_bwpsize, NR_CellGroupConfig_t *cg) { - int bw = 0; - if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; - for (int i=0; ilist.count; i++) { - genericParameters = &BWP_list->list.array[i]->bwp_Common->genericParameters; - int curr_bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - if (curr_bw > bw) - bw = curr_bw; + int bw = scc_bwpsize; + if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) { + const NR_ServingCellConfig_t *servingCellConfig = cg->spCellConfig->spCellConfigDedicated; + if(servingCellConfig->downlinkBWP_ToAddModList) { + struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = servingCellConfig->downlinkBWP_ToAddModList; + for (int i=0; ilist.count; i++) { + NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; + int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (curr_bw > bw) + bw = curr_bw; + } } } - else - bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); return bw; } @@ -4221,3 +4221,521 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, } return valid; } + +//! Calculating number of bits set +uint8_t number_of_bits_set(uint8_t buf) { + uint8_t nb_of_bits_set = 0; + uint8_t mask = 0xff; + uint8_t index = 0; + + for (index=7; (buf & mask) && (index>=0) ; index--){ + if (buf & (1<>=1; + } + return nb_of_bits_set; +} + +void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t nb_resources, + nr_csi_report_t *csi_report) { + + if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { + if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; + else + /*! From Spec 38.331 + * nrofReportedRS + * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE + * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. + * When the field is absent the UE applies the value 1 + */ + csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; + } else + csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; + + if (nb_resources) { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources)); + csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + } else { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; + csi_report->CSI_report_bitlen.rsrp_bitlen = 0; + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; + } +} + +uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + uint8_t nb_allowed_ri, ri_bitlen; + uint8_t ri_restriction = 0; + + if (codebookConfig == NULL) { + csi_report->csi_meas_bitlen.ri_bitlen=0; + return ri_restriction; + } + + // codebook type1 single panel + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){ + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){ + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){ + if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present == + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { + // 4 ports + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + else { + // more than 4 ports + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + } + return ri_restriction; + } + else + AssertFatal(1==0,"Other configurations not yet implemented\n"); + return -1; +} + +void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + for(int i=0; i<8; i++) { + if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) + csi_report->csi_meas_bitlen.li_bitlen[i]=0; + else { + // codebook type1 single panel + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present) + csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2; + else + AssertFatal(1==0,"Other configurations not yet implemented\n"); + } + } +} + +void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) { + + // Table 5.2.2.2.1-2 in 38.214 for supported configurations + switch(morethantwo->n1_n2.present){ + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction): + *n1 = 2; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction): + *n1 = 2; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction): + *n1 = 3; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction): + *n1 = 6; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction): + *n1 = 8; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 3; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction): + *n1 = 12; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 4; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction): + *n1 = 8; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction): + *n1 = 16; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + default: + AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration"); + } +} + +void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, + int *x1, int *x2, int rank, int codebook_mode) { + + // Table 6.3.1.1.2-1 in 38.212 + switch(rank){ + case 1: + if(n2>1) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 2; + } + else { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); + *x2 = 4; + } + } + else{ + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 2; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 4; + } + } + break; + case 2: + if(n1*n2 == 2) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 3; + } + *x1 += 1; + } + else { + if(n2>1) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 3; + } + else { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); + *x2 = 3; + } + } + else{ + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 3; + } + } + *x1 += 2; + } + break; + case 3: + case 4: + if(n1*n2 == 2) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + if(n1*n2 >= 8) { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2; + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2; + *x2 = 1; + } + } + break; + case 5: + case 6: + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + break; + case 7: + case 8: + if(n1 == 4 && n2 == 1) { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + if(n1 > 2 && n2 == 2) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + } + break; + default: + AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n"); + } +} + + +void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + for(int i=0; i<8; i++) { + csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0; + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0; + if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) + return; + else { + if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) { + if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { + if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present == + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { + csi_report->N1 = 1; + csi_report->N2 = 1; + if (i==0) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2; + if (i==1) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1; + } + else { // more than two + int n1,n2,o1,o2,x1,x2; + get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo); + get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode); + csi_report->N1 = n1; + csi_report->N2 = n2; + csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode; + csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1; + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2; + } + } + else + AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n"); + } + else + AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n"); + } + } +} + +void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration; + + if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) { + for(int i=0; i<8; i++) { + if ((ri_restriction>>i)&0x01) { + csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4; + if(codebookConfig != NULL) { + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){ + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) { + if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present > + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { + // more than 4 antenna ports + if (i > 4) + csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB + } + } + } + } + } + else + csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0; + } + } + else + AssertFatal(1==0,"Sub-band CQI reporting not yet supported"); +} + +//!TODO : same function can be written to handle csi_resources +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) { + uint8_t csi_report_id = 0; + uint8_t nb_resources = 0; + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + NR_CSI_ResourceConfigId_t csi_ResourceConfigId; + struct NR_CSI_ResourceConfig *csi_resourceconfig; + + // for each CSI measurement report configuration (list of CSI-ReportConfig) + LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count); + for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + // MAC structure for CSI measurement reports (per UE and per report) + nr_csi_report_t *csi_report = &csi_report_template[csi_report_id]; + // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration + // (either CSI-RS or SSB) + csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; + // looking for CSI-ResourceConfig + int found_resource = 0; + int csi_resourceidx = 0; + while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) { + csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) + found_resource = 1; + csi_resourceidx++; + } + AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n", + csi_ResourceConfigId); + + long resourceType = csi_resourceconfig->resourceType; + + reportQuantity_type = csi_reportconfig->reportQuantity.present; + csi_report->reportQuantity_type = reportQuantity_type; + + // setting the CSI or SSB index list + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { + for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ + //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig + nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; + csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array; + csi_report->CSI_Index_list = NULL; + break; + } + } + } + else { + if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) { + AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL, + "Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n"); + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + //For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 + nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count; + csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array; + csi_report->SSB_Index_list = NULL; + break; + } + } + } + else AssertFatal(1==0,"Only periodic resource configuration currently supported\n"); + } + LOG_D(NR_MAC,"nb_resources %d\n",nb_resources); + // computation of bit length depending on the report type + switch(reportQuantity_type){ + case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP): + compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP): + compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + default: + AssertFatal(1==0,"Not yet supported CSI report quantity type"); + } + } +} + +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) { + + uint16_t csi_bitlen = 0; + uint16_t max_bitlen = 0; + L1_RSRP_bitlen_t *CSI_report_bitlen = NULL; + CSI_Meas_bitlen_t *csi_meas_bitlen = NULL; + + if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP || + csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) { + CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements + csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + + CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * + (CSI_report_bitlen->nb_ssbri_cri -1 ))); + } else { + csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements + uint16_t temp_bitlen; + for (int i=0; i<8; i++) { + temp_bitlen = (csi_meas_bitlen->cri_bitlen+ + csi_meas_bitlen->ri_bitlen+ + csi_meas_bitlen->li_bitlen[i]+ + csi_meas_bitlen->cqi_bitlen[i]+ + csi_meas_bitlen->pmi_x1_bitlen[i]+ + csi_meas_bitlen->pmi_x2_bitlen[i]); + if(temp_bitlen>max_bitlen) + max_bitlen = temp_bitlen; + } + csi_bitlen += max_bitlen; + } + + return csi_bitlen; +} \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 6caddcff78..3b76faeef1 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -105,7 +105,7 @@ uint8_t get_pusch_mcs_table(long *mcs_Table, uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, uint8_t unpaired, - frequency_range_t); + frequency_range_t); int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder); @@ -142,7 +142,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset); -int get_bw_tbslbrm(NR_BWP_t *genericParameters, +int get_bw_tbslbrm(int scc_bwpsize, NR_CellGroupConfig_t *cg); uint32_t nr_compute_tbslbrm(uint16_t table, @@ -234,4 +234,36 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rntiP); + +uint8_t number_of_bits_set(uint8_t buf); + +void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t nb_resources, + nr_csi_report_t *csi_report); + +uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + nr_csi_report_t *csi_report); + +void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo); + +void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, + int *x1, int *x2, int rank, int codebook_mode); + +void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template); + +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id); + #endif diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 4b37c19dff..7bbe8d68a7 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -74,7 +74,7 @@ extern uint8_t rb_table[34]; extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern uint8_t dlsch_ue_select_tbl_in_use; extern uint8_t new_dlsch_ue_select_tbl_in_use; -extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; +extern bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif*/ diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b0d41f317b..2804a9ec1e 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -190,7 +190,7 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; if (mac->frequency_range == FR1){ - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst.inOneGroup.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; } else{ @@ -343,7 +343,9 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10; cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; - cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; + + // NSA -> take ssb offset from SCS + cfg->ssb_table.ssb_subcarrier_offset = absolute_diff%(12*scs_scaling); switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -351,7 +353,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 3 : @@ -578,7 +580,7 @@ int nr_rrc_mac_config_req_ue_logicalChannelBearer( int cc_idP, uint8_t gNB_index, long logicalChannelIdentity, - boolean_t status){ + bool status){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); mac->logicalChannelBearer_exist[logicalChannelIdentity] = status; return 0; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 800e042464..35302eaafb 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -399,6 +399,11 @@ typedef struct { /// measured SSB RSRP in dBm short ssb_rsrp_dBm; + nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; + + /// measurements from CSI-RS + fapi_nr_csirs_measurements_t csirs_measurements; + /// Last NDI of UL HARQ processes uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES]; /// first ULTX of UL HARQ processes @@ -415,7 +420,7 @@ typedef struct { uint8_t BSR_reporting_active; /// LogicalChannelConfig has bearer. - boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID]; + bool logicalChannelBearer_exist[NR_MAX_NUM_LCID]; NR_UE_SCHEDULING_INFO scheduling_info; /// PHR @@ -546,7 +551,7 @@ typedef struct prach_association_pattern { // SSB details typedef struct ssb_info { - boolean_t transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration + bool transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index uint16_t nb_mapped_ro; // Total number of mapped ROs to this SSB index } ssb_info_t; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index caa4af4144..161799fb66 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -85,14 +85,12 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, \param cc_id component carrier id \param gNB_index gNB index \param long logicalChannelIdentity - \param boolean_t status*/ -int nr_rrc_mac_config_req_ue_logicalChannelBearer( - module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - long logicalChannelIdentity, - boolean_t status -); + \param bool status*/ +int nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, + int cc_idP, + uint8_t gNB_index, + long logicalChannelIdentity, + bool status); /**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config) \param module_id module id @@ -154,14 +152,14 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, */ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP); -/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) +/*! \fn bool update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) \brief get the rlc stats and update the bsr level for each lcid \param[in] Mod_id instance of the UE \param[in] frameP Frame index \param[in] slot slotP number \param[in] uint8_t gNB_index */ -boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index); +bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index); /*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value) \brief locate the BSR level in the table as defined in 38.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. @@ -196,6 +194,7 @@ int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer); int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind); int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); +int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements); uint32_t get_ssb_frame(uint32_t test); @@ -215,6 +214,18 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, NR_CSI_ResourceConfigId_t csi_ResourceConfigId, NR_CSI_MeasConfig_t *csi_MeasConfig); +uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig); + +uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig); + uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int csi_report_id, @@ -259,13 +270,6 @@ void get_bwp_info(NR_UE_MAC_INST_t *mac, NR_BWP_DownlinkCommon_t *get_bwp_downlink_common(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t dl_bwp_id); -uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, - uint8_t dci_format, - uint8_t dci_length, - uint16_t rnti, - uint64_t *dci_pdu, - dci_pdu_rel15_t *nr_pdci_info_extracted); - NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon); NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_t *pdsch_Config,NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h old mode 100755 new mode 100644 index 8b3f00af43..3bfeb29e2e --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h @@ -24,3 +24,4 @@ */ long nr_get_Pcmax(module_id_t mod_id); /** @}*/ + diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 735ff1bd54..507cdb2661 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -325,7 +325,7 @@ void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_ // ======================================= NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB int total_preambles_per_ssb; uint8_t ssb_nb_in_ro; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0e043208e4..0d9383eaf2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -134,6 +134,13 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { }; +static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + uint8_t dci_format, + uint8_t dci_length, + uint16_t rnti, + uint64_t *dci_pdu, + dci_pdu_rel15_t *nr_pdci_info_extracted); + void nr_ue_init_mac(module_id_t module_idP) { int i; @@ -957,7 +964,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (mac->scc || mac->scc_SIB || mac->cg) { NR_BWP_t genericParameters = mac->scc ? mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters : mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - bw_tbslbrm = get_bw_tbslbrm(&genericParameters, mac->cg); + int BWPSize = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + bw_tbslbrm = get_bw_tbslbrm(BWPSize, mac->cg); } else bw_tbslbrm = dlsch_config_pdu_1_0->BWPSize; @@ -985,7 +993,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3; // Sanity check for pucch_resource_indicator value received to check for false DCI. valid = 0; - if (mac->ULbwp[ul_bwp_id-1] && + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup&& @@ -1396,7 +1405,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4; NR_BWP_t genericParameters = mac->scc ? mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters : mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - int bw_tbslbrm = get_bw_tbslbrm(&genericParameters, mac->cg); + int BWPSize = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(BWPSize, mac->cg); dlsch_config_pdu_1_1->tbslbrm = nr_compute_tbslbrm(dlsch_config_pdu_1_1->mcs_table, bw_tbslbrm, nl_tbslbrm); @@ -1454,6 +1464,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr } +int8_t nr_ue_process_csirs_measurements(module_id_t module_id, + frame_t frame, + int slot, + fapi_nr_csirs_measurements_t *csirs_measurements) { + LOG_D(NR_MAC,"(%d.%d) Received CSI-RS measurements\n", frame, slot); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + memcpy(&mac->csirs_measurements, csirs_measurements, sizeof(*csirs_measurements)); + return 0; +} + void set_harq_status(NR_UE_MAC_INST_t *mac, uint8_t pucch_id, uint8_t harq_id, @@ -1512,13 +1532,12 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, NR_BWP_UplinkCommon_t *initialUplinkBWP; if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1]; - if (mac->cg && ubwp && + if (mac->cg && bwp_id > 1 && mac->ULbwp[bwp_id - 1] && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing; } else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; @@ -1581,7 +1600,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, // TODO verify if SR can be transmitted in this mode pucch_pdu->payload = (pucch->sr_payload << O_ACK) | pucch->ack_payload; - } else if (pucch->pucch_resource != NULL) { @@ -1782,8 +1800,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, default: AssertFatal(1==0,"Group hopping flag undefined (0,1,2) \n"); } - - } @@ -2002,7 +2018,7 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) { * processing slots of reception/transmission * gNB_id identifier * -* RETURN : TRUE a valid resource has been found +* RETURN : true a valid resource has been found * * DESCRIPTION : return tx harq process identifier for given transmission slot * TS 38.213 9.2.1 PUCCH Resource Sets @@ -2132,7 +2148,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, int number_harq_feedback = 0; uint32_t dai_current = 0; uint32_t dai_max = 0; - bool two_transport_blocks = FALSE; + bool two_transport_blocks = false; int number_of_code_word = 1; int U_DAI_c = 0; int N_m_c_rx = 0; @@ -2154,7 +2170,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, bwpd->pdsch_Config->choice.setup && bwpd->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI && bwpd->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) { - two_transport_blocks = TRUE; + two_transport_blocks = true; number_of_code_word = 2; } @@ -2178,7 +2194,8 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, sched_frame = (sched_frame + 1) % 1024; } AssertFatal(sched_slot < slots_per_frame, "sched_slot was calculated incorrect %d\n", sched_slot); - LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n",dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common); + LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n", + dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common); /* check if current tx slot should transmit downlink acknowlegment */ if (sched_frame == frame && sched_slot == slot) { if (get_softmodem_params()->emulate_l1) { @@ -2254,7 +2271,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, * For a monitoring occasion of a PDCCH with DCI format 1_0 or DCI format 1_1 in at least one serving cell, * when a UE receives a PDSCH with one transport block and the value of higher layer parameter maxNrofCodeWordsScheduledByDCI is 2, * the HARQ-ACK response is associated with the first transport block and the UE generates a NACK for the second transport block - * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = FALSE) and generates HARQ-ACK value of ACK for the second + * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = false) and generates HARQ-ACK value of ACK for the second * transport block if spatial bundling is applied. */ @@ -2265,7 +2282,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, ack_data[code_word][i] = 0; /* nack data transport block which has been missed */ number_harq_feedback++; } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { dai_total[code_word][i] = dai[code_word][i]; /* for a single cell, dai_total is the same as dai of first cell */ } } @@ -2296,7 +2313,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, o_ACK = o_ACK | (ack_data[1][m] << O_bit_number_cw1); } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { O_bit_number_cw0 = (8 * j) + 2*(V_temp - 1); } else { @@ -2311,7 +2328,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, j = j + 1; } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { O_ACK = 2 * ( 4 * j + V_temp2); /* for two transport blocks */ } else { @@ -2340,17 +2357,16 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; NR_PUCCH_Config_t *pucch_Config = NULL; int scs; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1]; NR_BWP_UplinkCommon_t *initialUplinkBWP; if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - if (mac->cg && ubwp && + if (mac->cg && bwp_id && mac->ULbwp[bwp_id - 1] && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing; } else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; @@ -2433,11 +2449,9 @@ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){ // start the sr-prohibittimer : rel 9 and above if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured mac->scheduling_info.sr_ProhibitTimer--; - mac->scheduling_info. - sr_ProhibitTimer_Running = 1; + mac->scheduling_info.sr_ProhibitTimer_Running = 1; } else { - mac->scheduling_info. - sr_ProhibitTimer_Running = 0; + mac->scheduling_info.sr_ProhibitTimer_Running = 0; } //mac->ul_active =1; return (1); //instruct phy to signal SR @@ -2560,13 +2574,17 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: + n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: + n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: - LOG_E(NR_MAC,"Measurement report based on CSI-RS not available\n"); + LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present); break; default: AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present); @@ -2654,6 +2672,122 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, return bits; } +uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig) { + + int n_bits = 0; + uint32_t temp_payload = 0; + + for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { + + struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) { + + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + + nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId]; + compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); + n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId); + + int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; + int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen; + int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator]; + int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator]; + int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator]; + int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); + + // TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0 + temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) | + (mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) | + (mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) | + (mac->csirs_measurements.cqi<csi_part1_payload = temp_payload; + return n_bits; +} + +uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig) { + + int n_bits = 0; + uint32_t temp_payload = 0; + + for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { + + struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) { + + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + + nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId]; + compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); + n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId); + + int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; + int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen; + int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen; + + if (cri_ssbri_bitlen > 0) { + LOG_E(NR_MAC, "Implementation for cri_ssbri_bitlen>0 is not supported yet!\n");; + } + + // TODO: Improvements will be needed to cri_ssbri_bitlen>0 + // TS 38.133 - Table 10.1.6.1-1 + int rsrp_dBm = mac->csirs_measurements.rsrp_dBm; + if (rsrp_dBm < -140) { + temp_payload = 16; + } else if (rsrp_dBm > -44) { + temp_payload = 113; + } else { + temp_payload = mac->csirs_measurements.rsrp_dBm + 157; + } + + reverse_n_bits((uint8_t *)&temp_payload, n_bits); + + LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen); + LOG_D(NR_MAC, "rsrp_bitlen = %d\n", rsrp_bitlen); + LOG_D(NR_MAC, "diff_rsrp_bitlen = %d\n", diff_rsrp_bitlen); + + LOG_D(NR_MAC, "n_bits = %d\n", n_bits); + LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload); + + break; + } + } + } + } + + pucch->csi_part1_payload = temp_payload; + return n_bits; +} // returns index from RSRP // according to Table 10.1.6.1-1 in 38.133 @@ -2734,7 +2868,7 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){ } -uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, +static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint8_t dci_format, uint8_t dci_size, uint16_t rnti, @@ -3582,7 +3716,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, #endif */ - LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); + LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index ad6bf3cdc4..8605550593 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -118,12 +118,13 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; // Get K2 from RRC configuration - NR_PUSCH_Config_t *pusch_config=mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL; + NR_PUSCH_Config_t *pusch_config= ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL; NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup; } - else if (mac->ULbwp[ul_bwp_id-1] && + else if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Common&& mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&& mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup && @@ -169,7 +170,7 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl // Calculate the index of the UL slot in mac->ul_config_request list. This is // based on the TDD pattern (slot configuration period) and number of UL+mixed // slots in the period. TS 38.213 Sec 11.1 - int mu = mac->ULbwp[ul_bwp_id-1] ? + int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; const int n = nr_slots_per_frame[mu]; @@ -205,7 +206,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; } - NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? + NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd? ubwpd->pusch_Config->choice.setup: @@ -361,7 +362,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL); + NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL); AssertFatal(pusch_Config!=NULL,"pusch_Config shouldn't be null\n"); long transformPrecoder; @@ -581,7 +582,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, if (rar_grant) { // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 - NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1]; + NR_BWP_Uplink_t *ubwp = ul_bwp_id > 0 ? mac->ULbwp[ul_bwp_id - 1] : NULL; NR_BWP_UplinkDedicated_t *ibwp; int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype; NR_PUSCH_Config_t *pusch_Config=NULL; @@ -839,11 +840,15 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { - if (*dci_format != NR_UL_DCI_FORMAT_0_1) { - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; - } - } else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) { + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id - 1] && + pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled && + *dci_format != NR_UL_DCI_FORMAT_0_1) { + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; + } else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || + (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && + pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; } @@ -859,7 +864,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else N_PRB_oh = 0; /* PTRS */ - if (mac->ULbwp[ul_bwp_id-1] && + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup && @@ -928,15 +934,23 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo bool srs_scheduled = false; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + const NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; NR_SRS_Config_t *srs_config = NULL; - if (mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { + if (ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1]) { + if (mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && + mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->srs_Config) { + srs_config = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->srs_Config->choice.setup; + } + } else if (mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; - } else { + } + + if (!srs_config) { return false; } @@ -964,7 +978,6 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo continue; } - NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; NR_BWP_t ubwp = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters; @@ -1086,9 +1099,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in dcireq.dl_config_req = mac->dl_config_request; fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); - mac->if_module->scheduled_response(&scheduled_response); + mac->if_module->scheduled_response(&scheduled_response); + } } else { // this is for Msg2/Msg4 @@ -1247,7 +1261,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } //Check whether Regular BSR is triggered - if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == TRUE) { + if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == true) { // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures // outlined in Sections 5.4.4 an 5.4.5 of 38.321 mac->scheduling_info.SR_pending = 1; @@ -1260,10 +1274,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } -boolean_t +bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) { mac_rlc_status_resp_t rlc_status; - boolean_t bsr_regular_triggered = FALSE; + bool bsr_regular_triggered = false; uint8_t lcid; uint8_t lcgid; uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined @@ -1356,7 +1370,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_ which belong to any LCG and for which data is already available for transmission */ { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", module_idP, lcid, mac->scheduling_info.LCGID[lcid], @@ -1367,7 +1381,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_ // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission if (mac->scheduling_info.retxBSR_SF == 0) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) { LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n", @@ -1557,15 +1571,14 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, int delta = 0; NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1]; // Get the numerology to calculate the Tx frame and slot - int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : + int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? + mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? + mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon @@ -1628,7 +1641,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers uint8_t slot_shift_for_map; uint8_t map_shift; - boolean_t even_slot_invalid; + bool even_slot_invalid; int64_t s_map; uint8_t prach_conf_start_symbol; // Starting symbol of the PRACH occasions in the PRACH slot uint8_t N_t_slot; // Number of PRACH occasions in a 14-symbols PRACH slot @@ -1900,7 +1913,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs uint8_t required_nb_of_prach_conf_period; // Nb of PRACH configuration periods required to map all the SSBs diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 493a058e13..0f4e0539f2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -51,7 +51,6 @@ extern RAN_CONTEXT_t RC; //extern int l2_init_gNB(void); -extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list, @@ -160,7 +159,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sche } -void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { +void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; @@ -335,42 +334,32 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts cfg->num_tlv++; // SSB Table Configuration - int scs_scaling = 1<<(cfg->ssb_config.scs_common.value); - if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling*3; - if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling>>2; uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - uint16_t sco = absolute_diff%(12*scs_scaling); - // values of subcarrier offset larger than the limit only indicates CORESET for Type0-PDCCH CSS set is not present - int ssb_SubcarrierOffset_limit = 0; - int offset_scaling = 0; //15kHz - if(frequency_range == FR1) { - ssb_SubcarrierOffset_limit = 24; - if (ssb_SubcarrierOffsetssb_config.scs_common.value; - } else - ssb_SubcarrierOffset_limit = 12; - if (ssb_SubcarrierOffsetssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling) - 10; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total + const int scaling_5khz = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1; + int sco = (absolute_diff/scaling_5khz) % 24; + if(frequency_range == FR2) + sco >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for + const int scs_scaling = frequency_range == FR2 ? 1 << (*scc->ssbSubcarrierSpacing - 2) : 1 << *scc->ssbSubcarrierSpacing; + cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scaling_5khz) - 10*scs_scaling; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total cfg->ssb_table.ssb_offset_point_a.tl.tag = NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG; cfg->num_tlv++; cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG; cfg->num_tlv++; - cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset<ssb_table.ssb_subcarrier_offset.value = sco; cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->num_tlv++; + RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; + RC.nrmac[Mod_idP]->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value; + switch (scc->ssb_PositionsInBurst->present) { case 1 : cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 3 : @@ -462,8 +451,7 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S return -1; } NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; - const uint16_t sf_ahead = 6/(0x01<0); - const uint16_t sl_ahead = sf_ahead * (0x01<if_inst->sl_ahead; sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<rnti, rrc_reconfiguration_delay); @@ -471,7 +459,6 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S } int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, int sib1_tda, @@ -486,19 +473,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, if (scc != NULL ) { AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present); - /* dimension UL_tti_req_ahead for number of slots in frame */ const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - RC.nrmac[Mod_idP]->UL_tti_req_ahead[0] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t)); - AssertFatal(RC.nrmac[Mod_idP]->UL_tti_req_ahead[0], - "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); - /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler - * consider that scheduler runs sl_ahead: the first sl_ahead slots are - * already "in the past" and thus we put frame 1 instead of 0! */ - for (int i = 0; i < n; ++i) { - nfapi_nr_ul_tti_request_t *req = &RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][i]; - req->SFN = i < (RC.nrmac[Mod_idP]->if_inst->sl_ahead-1); - req->Slot = i; - } RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL = calloc(n * MAX_BWP_SIZE, sizeof(uint16_t)); AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL, @@ -509,7 +484,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int num_pdsch_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP; RC.nrmac[Mod_idP]->xp_pdsch_antenna_ports = pdsch_AntennaPorts.XP; config_common(Mod_idP, - ssb_SubcarrierOffset, num_pdsch_antenna_ports, pusch_AntennaPorts, scc); @@ -523,7 +497,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, printf("Waiting for PHY_config_req\n"); } } - RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset; RC.nrmac[Mod_idP]->minRXTXTIMEpdsch = minRXTXTIMEpdsch; NR_PHY_Config_t phycfg; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 385cf5af16..c87aa68f75 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -68,6 +68,8 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP); + nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; nfapi_nr_ul_tti_request_t *future_ul_tti_req = diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 6daa68afed..745fc1ae2b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -398,7 +398,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot, - NR_ServingCellConfigCommon_t *scc, + int mu, NR_ServingCellConfigCommon_t *scc, frame_type_t frame_type, uint16_t monitoring_slot_period, uint16_t monitoring_offset,uint8_t beam_index, @@ -407,10 +407,9 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, // preferentially we schedule the msg2 in the mixed slot or in the last dl slot // if they are allowed by search space configuration - uint8_t mu = *scc->ssbSubcarrierSpacing; uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; uint8_t slot_window; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int n_slots_frame = nr_slots_per_frame[mu]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; // number of mixed slot or of last dl slot if there is no mixed slot uint8_t last_dl_slot_period = n_slots_frame-1; @@ -516,7 +515,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, int16_t timing_offset){ uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL - NR_SearchSpace_t *ss; uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; @@ -567,20 +565,8 @@ void nr_initiate_ra_proc(module_id_t module_idP, else ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - // This should be handled differently when we use the initialBWP for RA - ra->dl_bwp_id = 0;//TODO - ra->ul_bwp_id = 0; - NR_BWP_Downlink_t *bwp=NULL; - if (ra->CellGroup && ra->CellGroup->spCellConfig && ra->CellGroup->spCellConfig->spCellConfigDedicated) { - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { - ra->dl_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id - 1]; - } - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - ra->ul_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - } + // Configure RA BWP + configure_UE_BWP(nr_mac, scc, NULL, ra, NULL); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); @@ -611,37 +597,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->timing_offset = timing_offset; ra->preamble_slot = slotP; - NR_SearchSpaceId_t ra_SearchSpace = 0; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; - NR_BWP_t *genericParameters = NULL; - if(bwp) { - commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &bwp->bwp_Common->genericParameters; - } else { - commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); - - // Common SearchSpace list - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - ss = commonSearchSpaceList->list.array[i]; - if (ss->searchSpaceId == ra_SearchSpace) - ra->ra_ss = ss; - } - - AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); - - ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); - ra->sched_pdcch = set_pdcch_structure(nr_mac, - ra->ra_ss, - ra->coreset, - scc, - genericParameters, - &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); - // retrieving ra pdcch monitoring period and offset find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); @@ -649,6 +604,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, slotP, &msg2_frame, &msg2_slot, + ra->DL_BWP.scs, scc, frame_type, monitoring_slot_period, @@ -656,7 +612,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, beam_index, cc->num_active_ssb, nr_mac->tdd_beam_association, - nr_mac->if_inst->sl_ahead); + nr_mac->if_inst->sl_ahead); ra->Msg2_frame = msg2_frame; ra->Msg2_slot = msg2_slot; @@ -738,22 +694,10 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; - NR_BWP_Uplink_t *ubwp = NULL; - NR_BWP_UplinkDedicated_t *ubwpd = NULL; - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - NR_BWP_t *genericParameters = NULL; - if(ra->CellGroup) { - ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id-1]; - ubwpd = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - genericParameters = &ubwp->bwp_Common->genericParameters; - pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - genericParameters = &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - pusch_TimeDomainAllocationList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - int mu = genericParameters->subcarrierSpacing; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList; + int mu = ul_bwp->scs; uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; @@ -763,7 +707,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t int16_t *tdd_beam_association = nr_mac->tdd_beam_association; if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { // FR2 - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int n_slots_frame = nr_slots_per_frame[mu]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd,"Dynamic TDD not handled yet\n"); uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); @@ -775,12 +719,11 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t tdd_beam_association[num_tdd_period] = ra->beam_id; } - int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; int fh = 0; - int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; int StartSymbolIndex, NrOfSymbols; SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; + int mappingtype = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; @@ -821,7 +764,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t fill_msg3_pusch_pdu(pusch_pdu, scc, ra->msg3_round, startSymbolAndLength, - ra->rnti, scs, + ra->rnti, mu, BWPSize, BWPStart, mappingtype, fh, rbStart, ra->msg3_nb_rb); @@ -843,7 +786,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -883,26 +826,23 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; config_uldci(sib1, - ubwp, - ubwpd, scc, pusch_pdu, &uldci_payload, - NR_UL_DCI_FORMAT_0_0, ra->Msg3_tda_id, ra->msg3_TPC, - 0, // not used in format 0_0 - ra->ul_bwp_id); + &ra->UL_BWP); fill_dci_pdu_rel15(scc, ra->CellGroup, + &ra->DL_BWP, dci_pdu, &uldci_payload, NR_UL_DCI_FORMAT_0_0, NR_RNTI_TC, pusch_pdu->bwp_size, - ra->ul_bwp_id, - coresetid, + ul_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // Mark the corresponding RBs as used @@ -923,13 +863,11 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ra->Msg3_slot = sched_slot; } - } void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Uplink_t *ubwp, sub_frame_t current_slot, frame_t current_frame, NR_RA_t *ra, @@ -938,21 +876,18 @@ void nr_get_Msg3alloc(module_id_t module_id, // msg3 is scheduled in mixed slot in the following TDD period uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes - frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type; - int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + + int mu = ul_bwp->scs; int StartSymbolIndex = 0; int NrOfSymbols = 0; int startSymbolAndLength = 0; int temp_slot = 0; ra->Msg3_tda_id = 16; // initialization to a value above limit - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = nr_slots_per_frame[mu]; @@ -1016,10 +951,9 @@ void nr_get_Msg3alloc(module_id_t module_id, int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - if (ra->CellGroup) { - NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id - 1]; - int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (bwpSize != ul_bwp->BWPSize || bwpStart != ul_bwp->BWPStart) { + int act_bwp_start = ul_bwp->BWPStart; + int act_bwp_size = ul_bwp->BWPSize; if (!((bwpStart >= act_bwp_start) && ((bwpStart+bwpSize) <= (act_bwp_start+act_bwp_size)))) bwpStart = act_bwp_start; } @@ -1054,7 +988,6 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, int mappingtype, int fh, int msg3_first_rb, int msg3_nb_rb) { - int start_symbol_index,nr_of_symbols; SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); @@ -1090,13 +1023,16 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->vrb_to_prb_mapping = 0; pusch_pdu->frequency_hopping = fh; - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + //pusch_pdu->tx_direct_current_location; + //The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, + //which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, + //which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] pusch_pdu->uplink_frequency_shift_7p5khz = 0; //Resource Allocation in time domain pusch_pdu->start_symbol_index = start_symbol_index; pusch_pdu->nr_of_symbols = nr_of_symbols; //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round]; + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round%4]; pusch_pdu->pusch_data.harq_process_id = 0; pusch_pdu->pusch_data.new_data_indicator = 1; pusch_pdu->pusch_data.num_cb = 0; @@ -1126,9 +1062,10 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) { - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; if (ra->state == RA_IDLE) { LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -1161,20 +1098,11 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - int fh = 0; - int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; - int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; - - if (ra->CellGroup) { - NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id - 1]; - - startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; - mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0; - } + const int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int scs = ul_bwp->scs; + const int fh = (ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping) ? 1 : 0; + const int startSymbolAndLength = ul_bwp->tdaList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + const int mappingtype = ul_bwp->tdaList->list.array[ra->Msg3_tda_id]->mappingType; LOG_D(NR_MAC, "Frame %d, Slot %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", frameP, @@ -1203,6 +1131,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { @@ -1213,30 +1142,13 @@ 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_BWP_Downlink_t *bwp = NULL; - NR_ControlResourceSet_t *coreset = NULL; - NR_BWP_t *genericParameters = NULL; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL; - - if (ra->CellGroup && - ra->CellGroup->spCellConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]) { - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]; - genericParameters = &bwp->bwp_Common->genericParameters; - pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - else { - genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } + 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; if(*ss->controlResourceSetId!=0) { - BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + BWPStart = dl_bwp->BWPStart; BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } else { type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; @@ -1251,7 +1163,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); - coreset = ra->coreset; + NR_ControlResourceSet_t *coreset = ra->coreset; AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg2\n"); @@ -1303,7 +1215,6 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // 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 - const int bwpid = bwp ? bwp->bwp_Id : 0; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; if (!pdcch_pdu_rel15) { @@ -1313,7 +1224,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -1331,37 +1242,22 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // information to data and is reset every slot. const int pduindex = nr_mac->pdu_index[CC_id]++; - uint8_t mcsTableIdx = 0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) { - if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) - mcsTableIdx = 1; - else - mcsTableIdx = 2; - } - else mcsTableIdx = 0; + NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; int dmrsConfigType=0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) + 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_Config_t *pdsch_config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pdsch_Config ? bwp->bwp_Dedicated->pdsch_Config->choice.setup : NULL; - pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->rnti = ra->RA_rnti; pdsch_pdu_rel15->pduIndex = pduindex; pdsch_pdu_rel15->BWPSize = BWPSize; pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; @@ -1381,7 +1277,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->VRBtoPRBMapping = 0; pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(pdsch_Config, nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, @@ -1421,7 +1317,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->TBSize[0] = TBS; } - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, ra->CellGroup); + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, ra->CellGroup); pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, bw_tbslbrm, 1); @@ -1473,23 +1370,21 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra fill_dci_pdu_rel15(scc, ra->CellGroup, + dl_bwp, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, NR_DL_DCI_FORMAT_1_0, NR_RNTI_RA, BWPSize, - bwpid, - coresetid, + dl_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // DL TX request nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; // Program UL processing for Msg3 - NR_BWP_Uplink_t *ubwp = ra->CellGroup ? - ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1] : - NULL; - nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association); + nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); if(ra->cfra) { @@ -1527,6 +1422,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) { @@ -1536,23 +1432,8 @@ void nr_generate_Msg4(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_BWP_Downlink_t *bwp = NULL; - NR_ControlResourceSet_t *coreset = NULL; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL; - - if (ra->CellGroup && - ra->CellGroup->spCellConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]) { - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]; - pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - else { - pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - - coreset = ra->coreset; + 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"); @@ -1571,14 +1452,12 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_BWP_t *genericParameters = bwp ? & bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - long BWPStart = 0; long BWPSize = 0; NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; if(*ss->controlResourceSetId!=0) { - BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + BWPStart = dl_bwp->BWPStart; + BWPSize = dl_bwp->BWPSize; } else { type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; @@ -1629,7 +1508,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } const int delta_PRI=0; - int r_pucch = nr_get_pucch_resource(coreset, sched_ctrl->active_ubwp, NULL, CCEIndex); + int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI); @@ -1688,7 +1567,13 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos); - long dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; + 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) { @@ -1708,18 +1593,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 4; } - uint8_t mcsTableIdx = 0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) { - if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) - mcsTableIdx = 1; - else - mcsTableIdx = 2; - } - else mcsTableIdx = 0; + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; int rbStart = 0; int rbSize = 0; @@ -1764,7 +1638,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // 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 - const int bwpid = bwp ? bwp->bwp_Id : 0; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; if (!pdcch_pdu_rel15) { @@ -1774,7 +1647,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -1796,7 +1669,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->pduIndex = pduindex; pdsch_pdu_rel15->BWPSize = BWPSize; pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; int R = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); @@ -1804,7 +1677,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round]; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round%4]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -1825,7 +1698,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra int x_Overhead = 0; nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, ra->CellGroup); + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, ra->CellGroup); pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, bw_tbslbrm, 1); @@ -1890,13 +1764,14 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra fill_dci_pdu_rel15(scc, ra->CellGroup, + dl_bwp, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, NR_DL_DCI_FORMAT_1_0, NR_RNTI_TC, pdsch_pdu_rel15->BWPSize, - bwpid, - coresetid, + dl_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // Add padding header and zero rest out if there is space left @@ -1962,19 +1837,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra harq->round = 0; harq->ndi ^= 1; - // Pause scheduling according to: - // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_idP]->common_channels[0]; - const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - common_channels->ServingCellConfigCommon, - sib1); - uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? - NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; - - sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing); - LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frameP, slotP, UE->rnti, delay_ms); + sched_ctrl->rrc_processing_timer = 1; // No need to wait at this point in time, setting it to 1 just to enter in function nr_mac_update_timers + LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frameP, slotP, UE->rnti, 1); // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0; @@ -2006,16 +1870,11 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram // Pause scheduling according to: // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_id]->common_channels[0]; - const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - common_channels->ServingCellConfigCommon, - sib1); uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; - sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing); + sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frame, slot, UE->rnti, delay_ms); } else { LOG_I(NR_MAC, "(ue rnti 0x%04x) RA Procedure failed at Msg4!\n", ra->rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index e2ceadb889..a531a1c71c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -54,52 +54,6 @@ extern RAN_CONTEXT_t RC; - -uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) { - - int ratio; - switch (*scc->ssbSubcarrierSpacing) { - case NR_SubcarrierSpacing_kHz15: - AssertFatal(band <= 95, - "Band %ld is not possible for SSB with 15 kHz SCS\n", - band); - // no band available above 3GHz using 15kHz - ratio = 3; // NRARFCN step is 5 kHz - break; - case NR_SubcarrierSpacing_kHz30: - AssertFatal(band <= 96, - "Band %ld is not possible for SSB with 30 kHz SCS\n", - band); - if (band == 46 || band == 48 || band == 77 || - band == 78 || band == 79 || band == 96) // above 3GHz - ratio = 2; // NRARFCN step is 15 kHz - else - ratio = 6; // NRARFCN step is 5 kHz - break; - case NR_SubcarrierSpacing_kHz120: - AssertFatal(band >= 257, - "Band %ld is not possible for SSB with 120 kHz SCS\n", - band); - ratio = 2; // NRARFCN step is 15 kHz - break; - case NR_SubcarrierSpacing_kHz240: - AssertFatal(band >= 257, - "Band %ld is not possible for SSB with 240 kHz SCS\n", - band); - ratio = 4; // NRARFCN step is 15 kHz - break; - default: - AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n", - *scc->ssbSubcarrierSpacing); - } - - const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; - - return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB - -} - - void schedule_ssb(frame_t frame, sub_frame_t slot, NR_ServingCellConfigCommon_t *scc, nfapi_nr_dl_tti_request_body_t *dl_req, @@ -190,7 +144,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing; const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - uint16_t offset_pointa = get_ssboffset_pointa(scc,band); + const uint16_t offset_pointa = gNB->ssb_OffsetPointA; uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset; const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; @@ -207,8 +161,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -221,7 +176,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -235,8 +190,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -249,7 +205,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -264,8 +220,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; // FR2 is only TDD, to be fixed for flexible TDD @@ -286,7 +243,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -306,7 +263,7 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe //---------------------------------------- } -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) { +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) { AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != NR_SubcarrierSpacing_kHz240, @@ -314,7 +271,8 @@ void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart uint16_t *vrb_map = cc[CC_id].vrb_map; - for (int rb = 0; rb < 20; rb++) + const int extra_prb = ssb_subcarrier_offset > 0; + for (int rb = 0; rb < 20+extra_prb; rb++) vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4); } @@ -327,7 +285,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, int nrOfSymbols, uint16_t dlDmrsSymbPos, uint8_t candidate_idx, - int num_total_bytes) { + uint16_t num_total_bytes) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; @@ -352,7 +310,6 @@ uint32_t schedule_control_sib1(module_id_t module_id, } gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation; - gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = 0; gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = 0; // starting from mcs 0 gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; @@ -389,6 +346,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, 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); + int mcsTableIdx = 0; int rbSize = 0; uint32_t TBS = 0; do { @@ -400,8 +358,8 @@ uint32_t schedule_control_sib1(module_id_t module_id, else break; } - TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), - nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), + 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; } while (TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); @@ -443,7 +401,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, 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; 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; @@ -452,7 +410,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; nr_configure_pdcch(pdcch_pdu_rel15, gNB_mac->sched_ctrlCommon->coreset, - NULL, + true, // sib1 &gNB_mac->sched_ctrlCommon->sched_pdcch); nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; @@ -479,7 +437,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0]; + pdsch_pdu_rel15->rvIndex[0] = 0; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -494,9 +452,9 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, - gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx); + mcsTableIdx); pdsch_pdu_rel15->TBSize[0] = TBS; - pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos; @@ -545,6 +503,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, int rnti_type = NR_RNTI_SI; fill_dci_pdu_rel15(scc, + NULL, NULL, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, @@ -552,7 +511,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, rnti_type, pdsch_pdu_rel15->BWPSize, 0, - 0, + gNB_mac->sched_ctrlCommon->coreset, gNB_mac->cset0_bwp_size); LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); @@ -612,7 +571,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) // Get SIB1 uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8]; - uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload); + uint16_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload); LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length); LOG_D(NR_MAC,"SIB1: \n"); for (int k=0;kDL_req[CC_id].dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 3b5c9ffad4..6aee81fa67 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -365,6 +365,18 @@ void nr_store_dlsch_buffer(module_id_t module_id, } } +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) { + + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; + + harq->ndi ^= 1; + harq->round = 0; + UE->mac_stats.dl.errors++; + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); + +} + bool allocate_dl_retransmission(module_id_t module_id, frame_t frame, sub_frame_t slot, @@ -376,32 +388,25 @@ bool allocate_dl_retransmission(module_id_t module_id, gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + 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_CellGroupConfig_t *cg = UE->CellGroup; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; + //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; + } - NR_BWP_UplinkDedicated_t *ubwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); - - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; - const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; int rbSize = 0; 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"); @@ -430,11 +435,8 @@ bool allocate_dl_retransmission(module_id_t module_id, /* 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(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - cg, - sched_ctrl->active_bwp, - bwpd, tda, ps->nrOfLayers, sched_ctrl, @@ -445,11 +447,8 @@ bool allocate_dl_retransmission(module_id_t module_id, * that we have enough resources */ NR_pdsch_semi_static_t temp_ps = *ps; - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - cg, - sched_ctrl->active_bwp, - bwpd, tda, ps->nrOfLayers, sched_ctrl, @@ -520,7 +519,7 @@ bool allocate_dl_retransmission(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); if (alloc<0) { LOG_D(MAC, @@ -580,6 +579,7 @@ void pf_dl(module_id_t module_id, continue; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; @@ -619,12 +619,15 @@ void pf_dl(module_id_t module_id, /* Calculate coeff */ const NR_bler_options_t *bo = &mac->dl_bler; - const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28; + const int max_mcs_table = current_BWP->mcsTableIdx == 1 ? 27 : 28; const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table); - sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); + if (bo->harq_round_max == 1) + 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); - const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + 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, R, 1, /* rbSize */ @@ -651,37 +654,16 @@ void pf_dl(module_id_t module_id, /* Loop UE_sched to find max coeff and allocate transmission */ while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) { - NR_CellGroupConfig_t *cg = iterator->UE->CellGroup; - - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - - NR_BWP_UplinkDedicated_t *ubwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl; const uint16_t rnti = iterator->UE->rnti; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? - RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : - NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); + NR_UE_DL_BWP_t *dl_bwp = &iterator->UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &iterator->UE->current_UL_BWP; - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? - sched_ctrl->coreset->controlResourceSetId : - RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : - NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart if (sched_ctrl->available_dl_harq.head < 0) { @@ -721,7 +703,7 @@ void pf_dl(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0); if (alloc<0) { @@ -748,11 +730,8 @@ void pf_dl(module_id_t module_id, NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) { - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - iterator->UE->CellGroup, - sched_ctrl->active_bwp, - bwpd, tda, iterator->UE->layers, sched_ctrl, @@ -770,8 +749,8 @@ void pf_dl(module_id_t module_id, while (rbStart + max_rbSize < bwpSize && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap) max_rbSize++; - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + 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; uint32_t TBS = 0; uint16_t rbSize; @@ -817,30 +796,18 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t /* This is temporary and it assumes all UEs have the same BWP and TDA*/ NR_UE_info_t *UE=UE_info->list[0]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); int startSymbolIndex, nrOfSymbols; - const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ? - sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList : - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = current_BWP->tdaList; AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); + const int coresetid = sched_ctrl->coreset->controlResourceSetId; - NR_BWP_DownlinkDedicated_t *bwpd = - UE->CellGroup && - UE->CellGroup->spCellConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated ? - UE->CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; - - const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : current_BWP->BWPSize; + const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : current_BWP->BWPStart; const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols); uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; @@ -900,13 +867,12 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) { void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, sub_frame_t slot) { + gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) return; - //if (slot==7 || slot == 17) return; - /* PREPROCESSOR */ gNB_mac->pre_processor_dl(module_id, frame, slot); const int CC_id = 0; @@ -916,6 +882,7 @@ void nr_schedule_ue_spec(module_id_t module_id, UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; @@ -923,12 +890,6 @@ void nr_schedule_ue_spec(module_id_t module_id, UE->mac_stats.dl.current_bytes = 0; NR_CellGroupConfig_t *cg = UE->CellGroup; - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - /* update TA and set ta_apply every 10 frames. * Possible improvement: take the periodicity from input file. * If such UE is not scheduled now, it will be by the preprocessor later. @@ -995,24 +956,16 @@ void nr_schedule_ue_spec(module_id_t module_id, TBS, current_harq_pid, harq->round, - nr_rv_round_map[harq->round], + nr_rv_round_map[harq->round%4], harq->ndi, pucch->timing_indicator, pucch->frame, pucch->ul_slot, sched_pdsch->pucch_allocation, sched_ctrl->tpc1); - NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); - - NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space : gNB_mac->sched_ctrlCommon->search_space; - - const int bwp_id = bwp ? bwp->bwp_Id : 0; - const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId; + const int bwp_id = current_BWP->bwp_id; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid]; @@ -1026,8 +979,8 @@ void nr_schedule_ue_spec(module_id_t module_id, dl_req->nPDUs += 1; pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); - NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset; - nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch); + NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; + nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; } @@ -1049,22 +1002,22 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->BWPSize = gNB_mac->cset0_bwp_size; pdsch_pdu->BWPStart = gNB_mac->cset0_bwp_start; } else { - pdsch_pdu->BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + pdsch_pdu->BWPSize = current_BWP->BWPSize; + pdsch_pdu->BWPStart = current_BWP->BWPStart; } - pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing; - pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0; + pdsch_pdu->SubcarrierSpacing = current_BWP->scs; + pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0; // Codeword information pdsch_pdu->NrOfCodewords = 1; //number of information bits per 1024 coded bits expressed in 0.1 bit units pdsch_pdu->targetCodeRate[0] = R; pdsch_pdu->qamModOrder[0] = Qm; pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs; - pdsch_pdu->mcsTable[0] = ps->mcsTableIdx; + pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx; AssertFatal(harq!=NULL,"harq is null\n"); - AssertFatal(harq->round<4,"%d",harq->round); - pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round]; + AssertFatal(harq->rounddl_bler.harq_round_max,"%d",harq->round); + pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4]; pdsch_pdu->TBSize[0] = TBS; pdsch_pdu->dataScramblingId = *scc->physCellId; pdsch_pdu->nrOfLayers = nrOfLayers; @@ -1098,22 +1051,17 @@ void nr_schedule_ue_spec(module_id_t module_id, csi_report->codebook_mode); } // TBS_LBRM according to section 5.4.2.1 of 38.212 - long *maxMIMO_Layers = cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; + long *maxMIMO_Layers = current_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers; AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n"); int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4; // Maximum number of PRBs across all configured DL BWPs - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, cg); - pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(ps->mcsTableIdx, + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, cg); + pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx, bw_tbslbrm, nl_tbslbrm); - NR_PDSCH_Config_t *pdsch_Config=NULL; - - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup) - pdsch_Config = bwp->bwp_Dedicated->pdsch_Config->choice.setup; + NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config; /* Check and validate PTRS values */ struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS = @@ -1160,14 +1108,11 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_pdu_rel15_t dci_payload; memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); // bwp indicator - const int n_dl_bwp = bwp ? cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0; - AssertFatal(n_dl_bwp <= NR_MAX_NUM_BWP, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp); - // as per table 7.3.1.1.2-1 in 38.212 - dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0; + dci_payload.bwp_indicator.val = current_BWP->n_dl_bwp < 4 ? bwp_id : bwp_id - 1; - if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, - "Only frequency resource allocation type 1 is currently supported\n"); + AssertFatal(pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize, pdsch_pdu->rbStart, @@ -1203,19 +1148,17 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.tpc, pucch->timing_indicator); - int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ? - NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0; - const int rnti_type = NR_RNTI_C; fill_dci_pdu_rel15(scc, cg, + current_BWP, dci_pdu, &dci_payload, - dci_format, + current_BWP->dci_format, rnti_type, pdsch_pdu->BWPSize, - bwp ? bwp->bwp_Id : 0, - coresetid, + bwp_id, + sched_ctrl->coreset, gNB_mac->cset0_bwp_size); LOG_D(NR_MAC, @@ -1296,7 +1239,7 @@ void nr_schedule_ue_spec(module_id_t module_id, lcid < 4 ? "DCCH" : "DTCH", lcid, ndata, - bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG)); + bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); if (len == 0) break; @@ -1327,6 +1270,8 @@ void nr_schedule_ue_spec(module_id_t module_id, header->L = htons(bufEnd-buf); dlsch_total_bytes += bufEnd-buf; + for (; ((intptr_t)buf) % 4; buf++) + *buf = lrand48() & 0xff; for (; buf < bufEnd - 3; buf += 4) { uint32_t *buf32 = (uint32_t *)buf; *buf32 = lrand48(); @@ -1355,6 +1300,8 @@ void nr_schedule_ue_spec(module_id_t module_id, /* 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; // 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 808fc613f1..e474315de7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -195,17 +195,18 @@ void nr_preprocessor_phytest(module_id_t module_id, NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0]; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; 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(NULL, scc, UE->CellGroup, sched_ctrl->active_bwp, NULL, tda, target_dl_Nl,sched_ctrl , ps); + nr_set_pdsch_semi_static(dl_bwp, scc, tda, target_dl_Nl,sched_ctrl , ps); /* find largest unallocated chunk */ - const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int bwpSize = dl_bwp->BWPSize; + const int BWPStart = dl_bwp->BWPStart; int rbStart = 0; int rbSize = 0; @@ -278,7 +279,7 @@ void nr_preprocessor_phytest(module_id_t module_id, __func__, UE->rnti); - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); if (alloc < 0) { LOG_D(MAC, @@ -308,9 +309,9 @@ void nr_preprocessor_phytest(module_id_t module_id, sched_pdsch->rbSize = rbSize; sched_pdsch->mcs = target_dl_mcs; + 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->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, sched_pdsch->R, sched_pdsch->rbSize, @@ -340,7 +341,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; NR_UE_info_t *UE = nr_mac->UE_info.list[0]; AssertFatal(nr_mac->UE_info.list[1] == NULL, @@ -351,9 +351,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ const int CC_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int mu = ul_bwp->scs; - const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = - sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ul_bwp->tdaList; const int temp_tda = get_ul_tda(nr_mac, scc, slot); if (temp_tda < 0) return false; @@ -361,7 +362,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ "time domain assignment %d >= %d\n", temp_tda, tdaList->list.count); - int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, temp_tda, mu); + int K2 = get_K2(ul_bwp->tdaList, temp_tda, mu); const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_slot); @@ -377,33 +378,19 @@ 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; - const long f = (sched_ctrl->active_bwp && sched_ctrl->search_space && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? - sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; - const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - uint8_t num_dmrs_cdm_grps_no_data = 1; - if ((target_ul_Nl==4)||(target_ul_Nl==3)) - num_dmrs_cdm_grps_no_data = 2; - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or + * 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->dci_format != dci_format - || ps->nrOfLayers != target_ul_Nl - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(NULL, scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data,target_ul_Nl,ps); + || 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; - const int bw = NRRIV2BW(sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int bw = ul_bwp->BWPSize; + const int BWPStart = ul_bwp->BWPStart; if (target_ul_bw>bw) rbSize = bw; @@ -466,10 +453,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ /* Calculate TBS from MCS */ ps->nrOfLayers = target_ul_Nl; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); - if (ps->pusch_Config->tp_pi2BPSK - && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + 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 + && ((ul_bwp->mcs_table == 3 && mcs < 2) || (ul_bwp->mcs_table == 4 && mcs < 6))) { sched_pusch->R >>= 1; sched_pusch->Qm <<= 1; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3cbffa608f..1475abc08a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -44,9 +44,12 @@ #include "OCG.h" #include "OCG_extern.h" +/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ #include "RRC/LTE/rrc_extern.h" #include "RRC/NR/nr_rrc_extern.h" +#include "RRC/NR/rrc_gNB_UE_context.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" @@ -245,54 +248,12 @@ void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) { } } -NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_BWP_t *genericParameters = NULL; - if (active_bwp) { - genericParameters = &active_bwp->bwp_Common->genericParameters; - } else if (ServingCellConfigCommon) { - genericParameters = &ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } else { - genericParameters = &sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - } - return genericParameters; -} - -NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_BWP_t *genericParameters = NULL; - if (active_ubwp) { - genericParameters = &active_ubwp->bwp_Common->genericParameters; - } else if (ServingCellConfigCommon) { - genericParameters = &ServingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP->genericParameters; - } else { - genericParameters = &sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters; - } - return genericParameters; -} - -NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp, - const NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if (active_bwp) { - tdaList = active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } else if (ServingCellConfigCommon) { - tdaList = ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } else { - tdaList = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - return tdaList; -} - - NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, void *bwp, NR_SearchSpace_t *ss, NR_SearchSpace__searchSpaceType_PR ss_type) { + NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space @@ -324,29 +285,22 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, } } -NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1, - NR_ServingCellConfigCommon_t *scc, +NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, NR_SearchSpace__searchSpaceType_PR target_ss) { int n = 0; - if(bwp_Dedicated) { + if(bwp_Dedicated) n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count; - } else if(scc) { + else n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; - } else { - n = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; - } for (int i=0;ipdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - } else if(scc) { + else ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; - } else { - ss = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; - } AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); if (ss->searchSpaceType->present == target_ss) { @@ -557,11 +511,8 @@ bool nr_find_nb_rb(uint16_t Qm, return *tbs >= bytes && *nb_rb <= nb_rb_max; } -void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *secondaryCellGroup, - const NR_BWP_Downlink_t *bwp, - const NR_BWP_DownlinkDedicated_t *bwpd0, int tda, uint8_t layers, NR_UE_sched_ctrl_t *sched_ctrl, @@ -569,39 +520,11 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, { bool reset_dmrs = false; - NR_BWP_DownlinkDedicated_t *bwpd = NULL; - if (bwp && bwp->bwp_Dedicated) { - bwpd = bwp->bwp_Dedicated; - } else { - bwpd = (NR_BWP_DownlinkDedicated_t*)bwpd0; - } - - // Prevent gNB to enable 256QAM table while the RRCProcessing timer is running. - // For example, after the RRC created RRC Reconfiguration message we need to prevent gNB to apply another MCS table - // before the RRC Reconfiguration being received by the UE, otherwise UE will not be able to decode PDSCH - // and the connection will drop. - if (sched_ctrl->rrc_processing_timer == 0) { - if (bwpd && - bwpd->pdsch_Config && - bwpd->pdsch_Config->choice.setup && - bwpd->pdsch_Config->choice.setup->mcs_Table) { - if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0) { - ps->mcsTableIdx = 1; - } else { - ps->mcsTableIdx = 2; - } - } else { - ps->mcsTableIdx = 0; - } - } - LOG_D(NR_MAC,"MCS Table Index: %d\n",ps->mcsTableIdx); - - NR_PDSCH_Config_t *pdsch_Config = NULL; - if (bwpd && bwpd->pdsch_Config) pdsch_Config = bwpd->pdsch_Config->choice.setup; + 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_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp, scc, sib1); + 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) { @@ -615,19 +538,7 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); - const long f = ((bwp || bwpd) && - sched_ctrl->search_space && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? - sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; - - int dci_format; - if (sched_ctrl->search_space) { - dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0; - } - else { - dci_format = NR_DL_DCI_FORMAT_1_0; - } - if (dci_format == NR_DL_DCI_FORMAT_1_0) { + if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { if (ps->nrOfSymbols == 2) ps->numDmrsCdmGrpsNoData = 1; else @@ -648,72 +559,38 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, 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(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb); + 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,"bwpd0 %p, bwpd %p : Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",bwpd0,bwpd,ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT); + 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); } -void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, - long dci_format, int tda, - uint8_t num_dmrs_cdm_grps_no_data, uint8_t nrOfLayers, NR_pusch_semi_static_t *ps) { - ps->dci_format = dci_format; ps->time_domain_allocation = tda; - NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if(ubwp) { - tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if(scc) { - tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + const int startSymbolAndLength = ul_bwp->tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); - ps->pusch_Config = ubwp && ubwp->bwp_Dedicated && ubwp->bwp_Dedicated->pusch_Config ? - ubwp->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); - if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) - ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; - else - ps->transform_precoding = *ps->pusch_Config->transformPrecoder; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - if (ps->transform_precoding) - ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, - 0, - ps->dci_format, - NR_RNTI_C, - target_ss, - false); - else { - ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_TableTransformPrecoder : NULL, - 1, - ps->dci_format, - NR_RNTI_C, - target_ss, - false); - num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol - } - ps->nrOfLayers = nrOfLayers; - ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + // 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); + else + ps->num_dmrs_cdm_grps_no_data = 2; /* DMRS calculations */ - ps->mapping_type = tdaList->list.array[tda]->mappingType; - ps->NR_DMRS_UplinkConfig = ps->pusch_Config ? + 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 ? - ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : - ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL; + 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 @@ -735,8 +612,8 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, 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 - ? num_dmrs_cdm_grps_no_data * 6 - : num_dmrs_cdm_grps_no_data * 4; + ? ps->num_dmrs_cdm_grps_no_data * 6 + : ps->num_dmrs_cdm_grps_no_data * 4; } #define BLER_UPDATE_FRAME 10 @@ -1003,25 +880,18 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, } void config_uldci(const NR_SIB1_t *sib1, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int dci_format, int time_domain_assignment, uint8_t tpc, - int n_ubwp, - int bwp_id) { + NR_UE_UL_BWP_t *ul_bwp) { - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters((NR_BWP_Uplink_t *)ubwp, - (NR_ServingCellConfigCommon_t *)scc, - (NR_SIB1_t *)sib1); - - const int bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int bwp_id = ul_bwp->bwp_id; + nr_dci_format_t dci_format = ul_bwp->dci_format; dci_pdu_rel15->frequency_domain_assignment.val = - PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw); + PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, ul_bwp->BWPSize); dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; dci_pdu_rel15->mcs = pusch_pdu->mcs_index; @@ -1029,9 +899,9 @@ void config_uldci(const NR_SIB1_t *sib1, dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; dci_pdu_rel15->tpc = tpc; - const NR_BWP_UplinkDedicated_t *ubwpd2 = (ubwp) ? ubwp->bwp_Dedicated : ubwpd; + NR_PUSCH_Config_t *pusch_Config = ul_bwp->pusch_Config; - if (ubwpd2) AssertFatal(ubwpd2->pusch_Config->choice.setup->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, + if (pusch_Config) AssertFatal(pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, "Only frequency resource allocation type 1 is currently supported\n"); switch (dci_format) { case NR_UL_DCI_FORMAT_0_0: @@ -1041,13 +911,11 @@ void config_uldci(const NR_SIB1_t *sib1, LOG_D(NR_MAC,"Configuring DCI Format 0_1\n"); dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator as per table 7.3.1.1.2-1 in 38.212 - dci_pdu_rel15->bwp_indicator.val = n_ubwp < 4 ? bwp_id : bwp_id - 1; + dci_pdu_rel15->bwp_indicator.val = ul_bwp->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; // SRS resource indicator - if (ubwpd2 && - ubwpd2->pusch_Config && - ubwpd2->pusch_Config->choice.setup && - ubwpd2->pusch_Config->choice.setup->txConfig != NULL) { - AssertFatal(*ubwpd2->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook, + if (pusch_Config && + pusch_Config->txConfig != NULL) { + AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, "Non Codebook configuration non supported\n"); dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS } @@ -1098,7 +966,7 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, - NR_BWP_t *bwp, + bool is_sib1, NR_sched_pdcch_t *pdcch) { @@ -1122,7 +990,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, pdcch_pdu->ShiftIndex = pdcch->ShiftIndex; if(coreset->controlResourceSetId == 0) { - if(bwp == NULL) + if(is_sib1) pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; else pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0; @@ -1135,11 +1003,10 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, } int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, + NR_PUCCH_Config_t *pucch_Config, int CCEIndex) { int r_pucch = -1; - if(bwp == NULL && bwpd == NULL) { + if(pucch_Config == NULL) { int n_rb,rb_offset; get_coreset_rballoc(coreset->frequencyDomainResources.buf,&n_rb,&rb_offset); const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE; @@ -1150,24 +1017,20 @@ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, } // This function configures pucch pdu fapi structure -void nr_configure_pucch(const NR_SIB1_t *sib1, - nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *CellGroup, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, - uint16_t rnti, + NR_UE_info_t* UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, int r_pucch) { - NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_Resource_t *pucchres; NR_PUCCH_ResourceSet_t *pucchresset; NR_PUCCH_FormatConfig_t *pucchfmt; NR_PUCCH_ResourceId_t *resource_id = NULL; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; long *id0 = NULL; int n_list, n_set; @@ -1179,12 +1042,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, uint16_t O_uci = O_csi + O_ack; - NR_PUSCH_Config_t *pusch_Config = NULL; - if(bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pusch_Config) { - pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup; - } else if(bwpd && bwpd->pusch_Config) { - pusch_Config = bwpd->pusch_Config->choice.setup; - } + NR_PUSCH_Config_t *pusch_Config = current_BWP->pusch_Config; long *pusch_id = pusch_Config ? pusch_Config->dataScramblingIdentityPUSCH : NULL; @@ -1194,14 +1052,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0; else id0 = scc->physCellId; - NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = NULL; - if(bwp) { - pucch_ConfigCommon = bwp->bwp_Common->pucch_ConfigCommon->choice.setup; - } else if(scc) { - pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup; - } else { - pucch_ConfigCommon = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup; - } + NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = current_BWP->pucch_ConfigCommon; // hop flags and hopping id are valid for any BWP switch (pucch_ConfigCommon->pucch_GroupHopping){ @@ -1229,18 +1080,14 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, else pucch_pdu->hopping_id = *scc->physCellId; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(bwp,scc, sib1); + pucch_pdu->bwp_size = current_BWP->BWPSize; + pucch_pdu->bwp_start = current_BWP->BWPStart; + pucch_pdu->subcarrier_spacing = current_BWP->scs; + pucch_pdu->cyclic_prefix = (current_BWP->cyclicprefix==NULL) ? 0 : *current_BWP->cyclicprefix; - pucch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pucch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - pucch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing; - pucch_pdu->cyclic_prefix = (genericParameters->cyclicPrefix==NULL) ? 0 : *genericParameters->cyclicPrefix; - if (r_pucch<0 || bwp ){ + NR_PUCCH_Config_t *pucch_Config = current_BWP->pucch_Config; + if (r_pucch<0 || pucch_Config){ LOG_D(NR_MAC,"pucch_acknak: Filling dedicated configuration for PUCCH\n"); - // we have either a dedicated BWP or Dedicated PUCCH configuration on InitialBWP - AssertFatal(bwp!=NULL || bwpd!=NULL,"We need one dedicated configuration for a BWP (neither additional or initial BWP has a dedicated configuration)\n"); - pucch_Config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pucch_Config ? - bwp->bwp_Dedicated->pucch_Config->choice.setup : bwpd->pucch_Config->choice.setup; AssertFatal(pucch_Config->resourceSetToAddModList!=NULL, "PUCCH resourceSetToAddModList is null\n"); @@ -1293,7 +1140,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, if (pucchres->pucch_ResourceId == *resource_id) { res_found = 1; pucch_pdu->prb_start = pucchres->startingPRB; - pucch_pdu->rnti = rnti; + pucch_pdu->rnti = UE->rnti; // FIXME why there is only one frequency hopping flag // what about inter slot frequency hopping? pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0; @@ -1382,8 +1229,8 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, LOG_D(NR_MAC,"Configure pucch: pucch_pdu->format_type %d pucch_pdu->bit_len_harq %d, pucch->pdu->bit_len_csi %d\n",pucch_pdu->format_type,pucch_pdu->bit_len_harq,pucch_pdu->bit_len_csi_part1); } else { // this is the default PUCCH configuration, PUCCH format 0 or 1 - LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, bwp %p)\n",r_pucch,bwp); - int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon; + LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, pucch_Config %p)\n",r_pucch,pucch_Config); + int rsetindex = *pucch_ConfigCommon->pucch_ResourceCommon; int prb_start, second_hop_prb, nr_of_symb, start_symb; set_r_pucch_parms(rsetindex, r_pucch, @@ -1394,7 +1241,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, &start_symb); pucch_pdu->prb_start = prb_start; - pucch_pdu->rnti = rnti; + pucch_pdu->rnti = UE->rnti; pucch_pdu->freq_hop_flag = 1; pucch_pdu->second_hop_prb = second_hop_prb; pucch_pdu->format_type = default_pucch_fmt[rsetindex]; @@ -1436,27 +1283,15 @@ void set_r_pucch_parms(int rsetindex, *start_symbol_index = default_pucch_firstsymb[rsetindex]; } - void prepare_dci(const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *current_BWP, + const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, - nr_dci_format_t format, - int bwp_id) { + nr_dci_format_t format) { AssertFatal(CellGroup!=NULL,"CellGroup shouldn't be null here\n"); - const NR_BWP_DownlinkDedicated_t *bwpd = NULL; - const NR_PDSCH_Config_t *pdsch_Config = NULL; - const NR_PDCCH_Config_t *pdcch_Config = NULL; - - if (bwp_id>0) { - bwpd=CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - } - else { - bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; - } - pdsch_Config = (bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL; - pdcch_Config = (bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL; - + const NR_PDSCH_Config_t *pdsch_Config = current_BWP ? current_BWP->pdsch_Config : NULL; switch(format) { case NR_UL_DCI_FORMAT_0_1: @@ -1494,7 +1329,7 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, if (pdsch_Config->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList != NULL) AssertFatal(1==0,"Aperiodic ZP CSI-RS currently not supported\n"); // transmission configuration indication - if (pdcch_Config->controlResourceSetToAddModList->list.array[0]->tci_PresentInDCI != NULL) + if (coreset->tci_PresentInDCI != NULL) AssertFatal(1==0,"TCI in DCI currently not supported\n"); //srs resource set if (CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching!=NULL) { @@ -1518,9 +1353,8 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, else dci_pdu_rel15->srs_request.val = 0; // CBGTI and CBGFI - if (CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup && - CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) + if (current_BWP->pdsch_servingcellconfig && + current_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) AssertFatal(1==0,"CBG transmission currently not supported\n"); break; default : @@ -1531,23 +1365,28 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *current_BWP, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, int N_RB, int bwp_id, - NR_ControlResourceSetId_t coreset_id, + NR_ControlResourceSet_t *coreset, uint16_t cset0_bwp_size) { uint8_t fsize = 0, pos = 0; uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload; *dci_pdu=0; - int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); + NR_ControlResourceSetId_t coreset_id = coreset->controlResourceSetId; + int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP, + scc->uplinkConfigCommon->initialUplinkBWP, + CellGroup, dci_pdu_rel15, dci_format, + rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); pdcch_dci_pdu->PayloadSizeBits = dci_size; AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) - prepare_dci(CellGroup, dci_pdu_rel15, dci_format, bwp_id); + prepare_dci(CellGroup, current_BWP, coreset, dci_pdu_rel15, dci_format); /// Payload generation switch (dci_format) { @@ -2295,30 +2134,12 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces } } -int get_dl_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) -{ - if (servingCellConfig->firstActiveDownlinkBWP_Id) - return *servingCellConfig->firstActiveDownlinkBWP_Id; - else if (servingCellConfig->defaultDownlinkBWP_Id) - return *servingCellConfig->defaultDownlinkBWP_Id; - else - return 1; -} - -int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) -{ - if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) - return *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; - else - return 1; -} - /* hack data to remove UE in the phy */ int rnti_to_remove[10]; volatile int rnti_to_remove_count; pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER; -void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) +void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; destroy_nr_list(&sched_ctrl->available_dl_harq); @@ -2327,6 +2148,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) destroy_nr_list(&sched_ctrl->available_ul_harq); destroy_nr_list(&sched_ctrl->feedback_ul_harq); destroy_nr_list(&sched_ctrl->retrans_ul_harq); + uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); const rnti_t rnti = UE->rnti; free(UE); @@ -2356,6 +2178,253 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) } } +// main function to configure parameters of current BWP +void configure_UE_BWP(gNB_MAC_INST *nr_mac, + NR_ServingCellConfigCommon_t *scc, + NR_UE_sched_ctrl_t *sched_ctrl, + NR_RA_t *ra, + NR_UE_info_t *UE) { + + AssertFatal((ra != NULL && UE == NULL) || (ra == NULL && UE != NULL), "RA and UE structures are mutually exlusive in BWP configuration\n"); + + NR_CellGroupConfig_t *CellGroup; + NR_UE_DL_BWP_t *DL_BWP; + NR_UE_UL_BWP_t *UL_BWP; + + if (ra) { + DL_BWP = &ra->DL_BWP; + UL_BWP = &ra->UL_BWP; + CellGroup = ra->CellGroup; + } + else { + DL_BWP = &UE->current_DL_BWP; + UL_BWP = &UE->current_UL_BWP; + CellGroup = UE->CellGroup; + } + NR_BWP_Downlink_t *dl_bwp = NULL; + NR_BWP_Uplink_t *ul_bwp = NULL; + NR_BWP_DownlinkDedicated_t *bwpd = NULL; + NR_BWP_UplinkDedicated_t *ubwpd = NULL; + DL_BWP->n_dl_bwp = 1; + UL_BWP->n_ul_bwp = 1; + int old_dl_bwp_id = DL_BWP->bwp_id; + int old_ul_bwp_id = UL_BWP->bwp_id; + + int target_ss; + + if (CellGroup && + CellGroup->spCellConfig && + CellGroup->spCellConfig->spCellConfigDedicated) { + + const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated; + DL_BWP->pdsch_servingcellconfig = servingCellConfig->pdsch_ServingCellConfig? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + + if(UE && UE->Msg3_dcch_dtch) { + // switching to initial BWP + DL_BWP->bwp_id = 0; + UL_BWP->bwp_id = 0; + UE->Msg3_dcch_dtch = false; + } + else { + // (re)configuring BWP + // TODO BWP switching not via RRC reconfiguration + // via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before + if (servingCellConfig->firstActiveDownlinkBWP_Id) + DL_BWP->bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id; + if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) + UL_BWP->bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; + } + + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; + if(bwpList) + DL_BWP->n_dl_bwp = bwpList->list.count; + if (DL_BWP->bwp_id>0) { + for (int i=0; ilist.count; i++) { + dl_bwp = bwpList->list.array[i]; + if(dl_bwp->bwp_Id == DL_BWP->bwp_id) + break; + } + AssertFatal(dl_bwp!=NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n",DL_BWP->bwp_id); + } + + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; + if(ubwpList) + UL_BWP->n_ul_bwp = ubwpList->list.count; + if (UL_BWP->bwp_id>0) { + for (int i=0; ilist.count; i++) { + ul_bwp = ubwpList->list.array[i]; + if(ul_bwp->bwp_Id == UL_BWP->bwp_id) + break; + } + AssertFatal(ul_bwp!=NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id); + } + + // selection of dedicated BWPs + if(dl_bwp) + bwpd = dl_bwp->bwp_Dedicated; + else + bwpd = servingCellConfig->initialDownlinkBWP; + if(ul_bwp) + ubwpd = ul_bwp->bwp_Dedicated; + else + ubwpd = servingCellConfig->uplinkConfig->initialUplinkBWP; + + DL_BWP->pdsch_Config = bwpd->pdsch_Config->choice.setup; + UL_BWP->pusch_Config = ubwpd->pusch_Config->choice.setup; + UL_BWP->pucch_Config = ubwpd->pucch_Config->choice.setup; + UL_BWP->srs_Config = ubwpd->srs_Config->choice.setup; + UL_BWP->csi_MeasConfig = servingCellConfig->csi_MeasConfig ? servingCellConfig->csi_MeasConfig->choice.setup : NULL; + } + else { + DL_BWP->bwp_id = 0; + DL_BWP->bwp_id = 0; + target_ss = NR_SearchSpace__searchSpaceType_PR_common; + DL_BWP->pdsch_Config = NULL; + UL_BWP->pusch_Config = NULL; + UL_BWP->pucch_Config = NULL; + UL_BWP->csi_MeasConfig = NULL; + } + + if (old_dl_bwp_id != DL_BWP->bwp_id) + LOG_I(NR_MAC, "Switching to DL-BWP %li\n", DL_BWP->bwp_id); + if (old_ul_bwp_id != UL_BWP->bwp_id) + LOG_I(NR_MAC, "Switching to UL-BWP %li\n", UL_BWP->bwp_id); + + // TDA lists + if (DL_BWP->bwp_id>0) + DL_BWP->tdaList = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + else + DL_BWP->tdaList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + + if(UL_BWP->bwp_id>0) + UL_BWP->tdaList = ul_bwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + else + UL_BWP->tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + + // setting generic parameters + NR_BWP_t dl_genericParameters = (DL_BWP->bwp_id>0 && dl_bwp) ? + dl_bwp->bwp_Common->genericParameters: + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + + DL_BWP->scs = dl_genericParameters.subcarrierSpacing; + DL_BWP->cyclicprefix = dl_genericParameters.cyclicPrefix; + DL_BWP->BWPSize = NRRIV2BW(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + DL_BWP->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + NR_BWP_t ul_genericParameters = (UL_BWP->bwp_id>0 && ul_bwp) ? + ul_bwp->bwp_Common->genericParameters: + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + + UL_BWP->scs = ul_genericParameters.subcarrierSpacing; + UL_BWP->cyclicprefix = ul_genericParameters.cyclicPrefix; + UL_BWP->BWPSize = NRRIV2BW(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + UL_BWP->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + // Set downlink MCS table + if (DL_BWP->pdsch_Config && + DL_BWP->pdsch_Config->mcs_Table) { + if (*DL_BWP->pdsch_Config->mcs_Table == 0) + DL_BWP->mcsTableIdx = 1; + else + DL_BWP->mcsTableIdx = 2; + } else + DL_BWP->mcsTableIdx = 0; + LOG_D(NR_MAC,"DL MCS Table Index: %d\n",DL_BWP->mcsTableIdx); + + if (UL_BWP->pusch_Config == NULL || !UL_BWP->pusch_Config->transformPrecoder) + UL_BWP->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + else + UL_BWP->transform_precoding = *UL_BWP->pusch_Config->transformPrecoder; + + if(UL_BWP->bwp_id>0) + UL_BWP->pucch_ConfigCommon = ul_bwp->bwp_Common->pucch_ConfigCommon->choice.setup; + else + UL_BWP->pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup; + + + if(UE) { + // setting PDCCH related structures for sched_ctrl + sched_ctrl->search_space = get_searchspace(scc, + bwpd, + target_ss); + sched_ctrl->coreset = get_coreset(nr_mac, + scc, + bwpd, + sched_ctrl->search_space, + target_ss); + + sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, + sched_ctrl->search_space, + sched_ctrl->coreset, + scc, + &dl_genericParameters, + nr_mac->type0_PDCCH_CSS_config); + + // set DL DCI format + DL_BWP->dci_format = (sched_ctrl->search_space->searchSpaceType && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? + (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1 ? + NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0) : + NR_DL_DCI_FORMAT_1_0; + // set UL DCI format + UL_BWP->dci_format = (sched_ctrl->search_space->searchSpaceType && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? + (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1 ? + NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : + NR_UL_DCI_FORMAT_0_0; + + if (UL_BWP->csi_MeasConfig) + compute_csi_bitlen (UL_BWP->csi_MeasConfig, UE->csi_report_template); + + } + + if(ra) { + // setting PDCCH related structures for RA + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; + NR_SearchSpaceId_t ra_SearchSpace = 0; + if(dl_bwp) { + commonSearchSpaceList = dl_bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *dl_bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } else { + commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + NR_SearchSpace_t * ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == ra_SearchSpace) + ra->ra_ss = ss; + } + AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); + + ra->coreset = get_coreset(nr_mac, scc, dl_bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); + ra->sched_pdcch = set_pdcch_structure(nr_mac, + ra->ra_ss, + ra->coreset, + scc, + &dl_genericParameters, + &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); + + UL_BWP->dci_format = NR_UL_DCI_FORMAT_0_0; + DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0; + } + + // Set uplink MCS table + long *mcs_Table = NULL; + if (UL_BWP->pusch_Config) + mcs_Table = UL_BWP->transform_precoding ? + UL_BWP->pusch_Config->mcs_Table : + UL_BWP->pusch_Config->mcs_TableTransformPrecoder; + + UL_BWP->mcs_table = get_pusch_mcs_table(mcs_Table, + UL_BWP->transform_precoding ? 0 : 1, + UL_BWP->dci_format, + NR_RNTI_C, + target_ss, + false); +} + //------------------------------------------------------------------------------ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup) { @@ -2374,6 +2443,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf } UE->rnti = rntiP; + UE->uid = uid_linear_allocator_new(&UE_info->uid_allocator); UE->CellGroup = CellGroup; if (CellGroup) @@ -2381,95 +2451,53 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf else UE->Msg4_ACKed = false; - if (CellGroup && - CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig && - CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) { - compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE); - } + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + memset(sched_ctrl, 0, sizeof(*sched_ctrl)); + sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */ + sched_ctrl->ta_update = 31; + sched_ctrl->sched_srs.frame = -1; + sched_ctrl->sched_srs.slot = -1; - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - memset(sched_ctrl, 0, sizeof(*sched_ctrl)); - sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */ - sched_ctrl->set_pmi = false; - sched_ctrl->ta_frame = 0; - sched_ctrl->ta_update = 31; - sched_ctrl->ta_apply = false; - sched_ctrl->ul_rssi = 0; - sched_ctrl->pucch_consecutive_dtx_cnt = 0; - sched_ctrl->pusch_consecutive_dtx_cnt = 0; - sched_ctrl->ul_failure = 0; - sched_ctrl->sched_srs.frame = -1; - sched_ctrl->sched_srs.slot = -1; - sched_ctrl->sched_srs.srs_scheduled = false; + // initialize UE BWP information + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + memset(dl_bwp, 0, sizeof(*dl_bwp)); + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + memset(ul_bwp, 0, sizeof(*ul_bwp)); + 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; - const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL; + /* 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; /* Set default BWPs */ - const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL; + sched_ctrl->next_dl_bwp_id = -1; + sched_ctrl->next_ul_bwp_id = -1; + AssertFatal(ul_bwp->n_ul_bwp <= NR_MAX_NUM_BWP, + "uplinkBWP_ToAddModList has %d BWP!\n", + ul_bwp->n_ul_bwp); - const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0; - sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL; - NR_BWP_t *genericParameters = sched_ctrl->active_bwp ? - &sched_ctrl->active_bwp->bwp_Common->genericParameters: - &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common; - const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - sched_ctrl->search_space = get_searchspace(sib1, - scc, - sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, - target_ss); - sched_ctrl->coreset = get_coreset(nr_mac, - scc, - sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, - sched_ctrl->search_space, - target_ss); - sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, - sched_ctrl->search_space, - sched_ctrl->coreset, - scc, - genericParameters, - NULL); - sched_ctrl->next_dl_bwp_id = -1; - sched_ctrl->next_ul_bwp_id = -1; - const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; - if (ubwpList) - AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP, - "uplinkBWP_ToAddModList has %d BWP!\n", - ubwpList->list.count); - const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0; - sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL; - - /* get Number of HARQ processes for this UE */ - if (servingCellConfig) - AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup, - "no pdsch-ServingCellConfig found for UE %04x\n", - UE->rnti); - const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; - // pdsch == NULL in SA -> will create default (8) number of HARQ processes - create_dl_harq_list(sched_ctrl, pdsch); - // add all available UL HARQ processes for this UE - // nb of ul harq processes not configurable - create_nr_list(&sched_ctrl->available_ul_harq, 16); - for (int harq = 0; harq < 16; harq++) - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); - create_nr_list(&sched_ctrl->feedback_ul_harq, 16); - create_nr_list(&sched_ctrl->retrans_ul_harq, 16); + /* get Number of HARQ processes for this UE */ + // pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes + create_dl_harq_list(sched_ctrl, dl_bwp->pdsch_servingcellconfig); + // add all available UL HARQ processes for this UE + // nb of ul harq processes not configurable + create_nr_list(&sched_ctrl->available_ul_harq, 16); + for (int harq = 0; harq < 16; harq++) + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); + create_nr_list(&sched_ctrl->feedback_ul_harq, 16); + create_nr_list(&sched_ctrl->retrans_ul_harq, 16); pthread_mutex_lock(&UE_info->mutex); int i; - for(i=0; ilist[i] == NULL) { UE_info->list[i] = UE; break; } + } if (i == MAX_MOBILES_PER_GNB) { LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP); - delete_nr_ue_data(UE, nr_mac->common_channels); + delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); pthread_mutex_unlock(&UE_info->mutex); return NULL; } @@ -2573,7 +2601,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) memcpy(UE_info->list, newUEs, sizeof(UE_info->list)); pthread_mutex_unlock(&UE_info->mutex); - delete_nr_ue_data(UE, nr_mac->common_channels); + delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); } void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) { @@ -2597,46 +2625,12 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { } -void get_pdsch_to_harq_feedback(NR_UE_info_t *UE, - int bwp_id, - NR_SearchSpace__searchSpaceType_PR ss_type, +void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, + nr_dci_format_t dci_format, int *max_fb_time, uint8_t *pdsch_to_harq_feedback) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - NR_BWP_DownlinkDedicated_t *bwpd=NULL; - NR_BWP_UplinkDedicated_t *ubwpd=NULL; - - if (ss_type == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { - AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE %04x\n",UE->rnti); - AssertFatal(CellGroup->spCellConfig!=NULL,"Cellgroup->spCellConfig is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated!=NULL,"CellGroup->spCellConfig->spCellConfigDedicated is null\n"); - } - if (bwp_id>0) { - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count >= bwp_id, - "CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count %d < bwp_id %d\n", - CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count,bwp_id); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count >= bwp_id, - "CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count %d < bwp_id %d\n", - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count,bwp_id); - - bwpd = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - ubwpd = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - } - else if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) { // this is an initialBWP - AssertFatal((bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP is null\n"); - AssertFatal((ubwpd=CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->uplnikConfig->initialUplinkBWP is null\n"); - } - NR_SearchSpace_t *ss=NULL; - - // common search type uses DCI format 1_0 - if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { + if (dci_format == NR_DL_DCI_FORMAT_1_0) { for (int i=0; i<8; i++) { pdsch_to_harq_feedback[i] = i+1; if(pdsch_to_harq_feedback[i]>*max_fb_time) @@ -2644,42 +2638,16 @@ void get_pdsch_to_harq_feedback(NR_UE_info_t *UE, } } else { - - // searching for a ue specific search space - int found=0; - AssertFatal(bwpd->pdcch_Config!=NULL,"bwpd->pdcch_Config is null\n"); - AssertFatal(bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL, - "bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList is null\n"); - for (int i=0;ipdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { - ss=bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); - if (ss->searchSpaceType->present == ss_type) { - found=1; - break; - } - } - AssertFatal(found==1,"Couldn't find a ue specific searchspace\n"); - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) { + AssertFatal(pucch_Config!=NULL,"pucch_Config shouldn't be null here\n"); + if(pucch_Config->dl_DataToUL_ACK != NULL) { for (int i=0; i<8; i++) { - pdsch_to_harq_feedback[i] = i+1; + pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i]; if(pdsch_to_harq_feedback[i]>*max_fb_time) *max_fb_time = pdsch_to_harq_feedback[i]; } } - else { - AssertFatal(ubwpd!=NULL,"ubwpd shouldn't be null here\n"); - if(ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK != NULL) { - for (int i=0; i<8; i++) { - pdsch_to_harq_feedback[i] = *ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[i]; - if(pdsch_to_harq_feedback[i]>*max_fb_time) - *max_fb_time = pdsch_to_harq_feedback[i]; - } - } - else - AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); - } + else + AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); } } @@ -2701,12 +2669,13 @@ void nr_csirs_scheduling(int Mod_idP, if (sched_ctrl->rrc_processing_timer > 0) { continue; } - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated || - !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue; + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; - NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + if (!ul_bwp->csi_MeasConfig) continue; + + NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL) { @@ -2714,9 +2683,6 @@ void nr_csirs_scheduling(int Mod_idP, int period, offset; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - NR_BWP_t *genericParameters = sched_ctrl->active_bwp ? - &sched_ctrl->active_bwp->bwp_Common->genericParameters : - &gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){ nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; @@ -2735,22 +2701,20 @@ void nr_csirs_scheduling(int Mod_idP, nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15; - csirs_pdu_rel15->subcarrier_spacing = genericParameters->subcarrierSpacing; - if (genericParameters->cyclicPrefix) - csirs_pdu_rel15->cyclic_prefix = *genericParameters->cyclicPrefix; + csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs; + if (dl_bwp->cyclicprefix) + csirs_pdu_rel15->cyclic_prefix = *dl_bwp->cyclicprefix; else csirs_pdu_rel15->cyclic_prefix = 0; // According to last paragraph of TS 38.214 5.2.2.3.1 - uint16_t BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - uint16_t BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - if (resourceMapping.freqBand.startingRB < BWPStart) { - csirs_pdu_rel15->start_rb = BWPStart; + if (resourceMapping.freqBand.startingRB < dl_bwp->BWPStart) { + csirs_pdu_rel15->start_rb = dl_bwp->BWPStart; } else { csirs_pdu_rel15->start_rb = resourceMapping.freqBand.startingRB; } - if (resourceMapping.freqBand.nrofRBs > (BWPStart + BWPSize - csirs_pdu_rel15->start_rb)) { - csirs_pdu_rel15->nr_of_rbs = BWPStart + BWPSize - csirs_pdu_rel15->start_rb; + if (resourceMapping.freqBand.nrofRBs > (dl_bwp->BWPStart + dl_bwp->BWPSize - csirs_pdu_rel15->start_rb)) { + csirs_pdu_rel15->nr_of_rbs = dl_bwp->BWPStart + dl_bwp->BWPSize - csirs_pdu_rel15->start_rb; } else { csirs_pdu_rel15->nr_of_rbs = resourceMapping.freqBand.nrofRBs; } @@ -2905,8 +2869,8 @@ void nr_csirs_scheduling(int Mod_idP, void nr_mac_update_timers(module_id_t module_id, frame_t frame, sub_frame_t slot) { - NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; + NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (sched_ctrl->rrc_processing_timer > 0) { @@ -2914,8 +2878,6 @@ void nr_mac_update_timers(module_id_t module_id, if (sched_ctrl->rrc_processing_timer == 0) { LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %04x\n", frame, slot, UE->rnti); - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_CellGroupConfig_t *cg = NULL; uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, //might be added prefix later @@ -2929,121 +2891,37 @@ void nr_mac_update_timers(module_id_t module_id, } NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; - const NR_ServingCellConfig_t *spCellConfigDedicated = cg && cg->spCellConfig ? cg->spCellConfig->spCellConfigDedicated : NULL; LOG_I(NR_MAC,"Modified rnti %04x with CellGroup\n", UE->rnti); process_CellGroup(cg,&UE->UE_sched_ctrl); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - const NR_PDSCH_ServingCellConfig_t *pdsch = spCellConfigDedicated ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL; + configure_UE_BWP(RC.nrmac[module_id], scc, sched_ctrl, NULL, UE); + if (get_softmodem_params()->sa) { // add all available DL HARQ processes for this UE in SA - create_dl_harq_list(sched_ctrl, pdsch); - } - - // If needed, update the Dedicated BWP - const int current_bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - const int current_ubwp_id = sched_ctrl->active_ubwp ? sched_ctrl->active_ubwp->bwp_Id : 0; - if (UE->Msg3_dcch_dtch) { - // 3GPP TS 38.321 Section 5.15 Bandwidth Part (BWP) operation - // Currently there are no PRACH occasions configured for any Dedicated BWP, so UE will switch to the initialDownlinkBWP - sched_ctrl->active_bwp = NULL; - if (current_bwp_id != 0) { - LOG_I(NR_MAC, "(%d.%d) Switching to initialDownlinkBWP\n", frame, slot); - } - // 3GPP TS 38.321 Section 5.15 Bandwidth Part (BWP) operation - // Currently there are no PRACH occasions configured for any Dedicated BWP, so UE will switch to the initialUplinkBWP - sched_ctrl->active_ubwp = NULL; - if (current_ubwp_id != 0) { - LOG_I(NR_MAC, "(%d.%d) Switching to initialUplinkBWP\n", frame, slot); - } - UE->Msg3_dcch_dtch = false; - } else if (spCellConfigDedicated && - spCellConfigDedicated->downlinkBWP_ToAddModList && - spCellConfigDedicated->uplinkConfig && - spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) { - sched_ctrl->active_bwp = spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[*spCellConfigDedicated->firstActiveDownlinkBWP_Id - 1]; - if (*spCellConfigDedicated->firstActiveDownlinkBWP_Id != current_bwp_id) { - LOG_I(NR_MAC, "(%d.%d) Switching to DL-BWP %li\n", frame, slot, sched_ctrl->active_bwp->bwp_Id); - } - sched_ctrl->active_ubwp = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id - 1]; - if (*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id != current_ubwp_id) { - LOG_I(NR_MAC, "(%d.%d) Switching to UL-BWP %li\n", frame, slot, sched_ctrl->active_ubwp->bwp_Id); - } - } - - // Update coreset/searchspace - NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; - NR_BWP_DownlinkDedicated_t *bwpd = NULL; - NR_BWP_t *genericParameters = NULL; - int target_ss = NR_SearchSpace__searchSpaceType_PR_common; - if (bwp) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = sched_ctrl->active_bwp->bwp_Dedicated; - genericParameters = &sched_ctrl->active_bwp->bwp_Common->genericParameters; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - (cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - sched_ctrl->search_space = get_searchspace(sib1, scc, (void*)bwpd, target_ss); - sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, (void*)bwpd, sched_ctrl->search_space, target_ss); - sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[module_id], - sched_ctrl->search_space, - sched_ctrl->coreset, - scc, - genericParameters, - RC.nrmac[module_id]->type0_PDCCH_CSS_config); - sched_ctrl->maxL = 2; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig && - cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) { - compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE); + 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(sib1, + nr_set_pdsch_semi_static(&UE->current_DL_BWP, scc, - cg, - bwp, - bwpd, tda, layers, sched_ctrl, ps); - NR_BWP_Uplink_t *ubwp = sched_ctrl->active_ubwp; - NR_BWP_UplinkDedicated_t *ubwpd = NULL; - if (ubwp) { - ubwpd = sched_ctrl->active_ubwp->bwp_Dedicated; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - (cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { - ubwpd = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - } NR_pusch_semi_static_t *ups = &sched_ctrl->pusch_semi_static; - int dci_format = get_dci_format(sched_ctrl); - const uint8_t num_dmrs_cdm_grps_no_data = (ubwp || ubwpd) ? 1 : 2; const uint8_t nrOfLayers = 1; const int utda = get_ul_tda(RC.nrmac[module_id], scc, slot); - nr_set_pusch_semi_static(sib1, + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - ubwp, - ubwpd, - dci_format, utda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ups); } @@ -3063,14 +2941,95 @@ void schedule_nr_bwp_switch(module_id_t module_id, UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (sched_ctrl->rrc_processing_timer == 0 && - UE->Msg4_ACKed && - ((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) || - (sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) { + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + if (sched_ctrl->rrc_processing_timer == 0 && UE->Msg4_ACKed && sched_ctrl->next_dl_bwp_id >= 0) { - LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", - frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id); - nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + int schedule_bwp_switching = false; + if (dl_bwp->bwp_id == 0) { + // Switching from Initial BWP to Dedicated BWP + if (sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0) { + schedule_bwp_switching = true; + LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from Initial DL BWP to %ld and from Initial UL BWP to %ld\n", + frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + } + } else if (dl_bwp->bwp_id != sched_ctrl->next_dl_bwp_id && ul_bwp->bwp_id != sched_ctrl->next_ul_bwp_id) { + // Switching between Dedicated BWPs + schedule_bwp_switching = true; + LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", + frame, slot, UE->rnti, dl_bwp->bwp_id, sched_ctrl->next_dl_bwp_id, ul_bwp->bwp_id, sched_ctrl->next_ul_bwp_id); + } + + if (schedule_bwp_switching) { + AssertFatal(sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0, "BWP switching from a Dedicated BWP to the Initial BWP not handled yet!"); + nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + } } } } + +void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid) { + + if(gNB->UL_tti_req_ahead[CCid]) return; + + gNB->UL_tti_req_ahead[CCid] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t)); + AssertFatal(gNB->UL_tti_req_ahead[CCid], + "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); + /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler + * consider that scheduler runs sl_ahead: the first sl_ahead slots are + * already "in the past" and thus we put frame 1 instead of 0! */ + for (int i = 0; i < n; ++i) { + nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][i]; + req->SFN = i < (gNB->if_inst->sl_ahead-1); + req->Slot = i; + } +} + +void send_initial_ul_rrc_message(module_id_t module_id, + int CC_id, + const NR_UE_info_t *UE, + rb_id_t srb_id, + const uint8_t *sdu, + sdu_size_t sdu_len) { + const gNB_MAC_INST *mac = RC.nrmac[module_id]; + const rnti_t rnti = UE->rnti; + LOG_W(MAC, + "[RAPROC] Received SDU for CCCH on SRB %ld length %d for UE %04x\n", + srb_id, sdu_len, rnti); + + /* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ + if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) { + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]); + ue_context_p->ue_id_rnti = rnti; + ue_context_p->ue_context.rnti = rnti; + ue_context_p->ue_context.random_ue_identity = rnti; + ue_context_p->ue_context.Srb0.Active = 1; + RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_id]->rrc_ue_head, ue_context_p); + } + + const NR_ServingCellConfigCommon_t *scc = RC.nrrrc[module_id]->carrier.servingcellconfigcommon; + const NR_ServingCellConfig_t *sccd = RC.nrrrc[module_id]->configuration.scd; + NR_CellGroupConfig_t cellGroupConfig = {0}; + fill_initial_cellGroupConfig(UE->uid, &cellGroupConfig, scc, sccd, &RC.nrrrc[module_id]->configuration); + + uint8_t du2cu_rrc_container[1024]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + &cellGroupConfig, + du2cu_rrc_container, + sizeof(du2cu_rrc_container)); + AssertFatal(enc_rval.encoded > 0, + "Could not encode cellGroupConfig for UE %04x, failed element %s\n", + rnti, + enc_rval.failed_type->name); + + const f1ap_initial_ul_rrc_message_t ul_rrc_msg = { + /* TODO: add mcc, mnc, cell_id, ..., is not available at MAC yet */ + .crnti = rnti, + .rrc_container = (uint8_t *) sdu, + .rrc_container_length = sdu_len, + .du2cu_rrc_container = (uint8_t *) du2cu_rrc_container, + .du2cu_rrc_container_length = (enc_rval.encoded + 7) / 8 + }; + mac->mac_rrc.initial_ul_rrc_message_transfer(module_id, &ul_rrc_msg); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index c156ebf36d..97e5f75e34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -36,19 +36,13 @@ extern RAN_CONTEXT_t RC; void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) { - gNB_MAC_INST *nrmac = RC.nrmac[module_id]; - NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - - NR_BWP_t ubwp = sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; srs_pdu->rnti = UE->rnti; srs_pdu->handle = 0; - srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; - srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; - srs_pdu->subcarrier_spacing = ubwp.subcarrierSpacing; + srs_pdu->bwp_size = current_BWP->BWPSize; + srs_pdu->bwp_start = current_BWP->BWPStart; + srs_pdu->subcarrier_spacing = current_BWP->scs; srs_pdu->cyclic_prefix = 0; srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; @@ -114,28 +108,21 @@ void nr_schedule_srs(int module_id, frame_t frame) { UE_iterator(UE_info->list, UE) { const int CC_id = 0; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; - NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.slot = -1; sched_ctrl->sched_srs.srs_scheduled = false; - if(!UE->Msg4_ACKed || sched_ctrl->rrc_processing_timer > 0) { + if((sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) || + sched_ctrl->rrc_processing_timer > 0) { continue; } - NR_SRS_Config_t *srs_config = NULL; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - srs_config = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; - } else { + NR_SRS_Config_t *srs_config = current_BWP->srs_Config; + if (!srs_config) continue; - } for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { @@ -163,14 +150,9 @@ void nr_schedule_srs(int module_id, frame_t frame) { continue; } - NR_BWP_t ubwp = sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present]; uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p); - - int n_slots_frame = nr_slots_per_frame[ubwp.subcarrierSpacing]; + int n_slots_frame = nr_slots_per_frame[current_BWP->scs]; // Check if UE will transmit the SRS in this frame if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index d64b9c43db..68900cda35 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -80,23 +80,13 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac, pucch->resource_indicator); NR_COMMON_channels_t * common_ch=nrmac->common_channels; NR_ServingCellConfigCommon_t *scc = common_ch->ServingCellConfigCommon; - NR_CellGroupConfig_t *cg=UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (pucch_Config %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n", + frame,slot,UE->current_UL_BWP.pucch_Config,pucch->r_pucch,pucch->frame,pucch->ul_slot); - LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n", - frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot); - - const NR_SIB1_t *sib1 = common_ch->sib1 ? common_ch->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - nr_configure_pucch(sib1, - pucch_pdu, + nr_configure_pucch(pucch_pdu, scc, - UE->CellGroup, - UE->UE_sched_ctrl.active_ubwp, - ubwpd, - UE->rnti, + UE, pucch->resource_indicator, pucch->csi_bits, pucch->dai_c, @@ -169,560 +159,22 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, } } - -//! Calculating number of bits set -uint8_t number_of_bits_set (uint8_t buf){ - uint8_t nb_of_bits_set = 0; - uint8_t mask = 0xff; - uint8_t index = 0; - - for (index=7; (buf & mask) && (index>=0) ; index--){ - if (buf & (1<>=1; - } - return nb_of_bits_set; -} - - -void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t nb_resources, - nr_csi_report_t *csi_report) { - - if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { - if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) - csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; - else - /*! From Spec 38.331 - * nrofReportedRS - * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE - * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. - * When the field is absent the UE applies the value 1 - */ - csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; - } else - csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; - - if (nb_resources) { - csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources)); - csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - } else { - csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; - csi_report->CSI_report_bitlen.rsrp_bitlen = 0; - csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; - } -} - - -uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - uint8_t nb_allowed_ri, ri_bitlen; - uint8_t ri_restriction = 0; - - if (codebookConfig == NULL) { - csi_report->csi_meas_bitlen.ri_bitlen=0; - return ri_restriction; - } - - // codebook type1 single panel - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){ - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){ - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){ - if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present == - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { - // 4 ports - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - else { - // more than 4 ports - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - } - return ri_restriction; - } - else - AssertFatal(1==0,"Other configurations not yet implemented\n"); - return -1; -} - -void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - for(int i=0; i<8; i++) { - if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) - csi_report->csi_meas_bitlen.li_bitlen[i]=0; - else { - // codebook type1 single panel - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present) - csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2; - else - AssertFatal(1==0,"Other configurations not yet implemented\n"); - } - } -} - -void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) { - - // Table 5.2.2.2.1-2 in 38.214 for supported configurations - switch(morethantwo->n1_n2.present){ - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction): - *n1 = 2; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction): - *n1 = 2; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction): - *n1 = 3; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction): - *n1 = 6; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction): - *n1 = 8; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 3; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction): - *n1 = 12; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 4; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction): - *n1 = 8; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction): - *n1 = 16; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - default: - AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration"); - } -} - -void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, - int *x1, int *x2, int rank, int codebook_mode) { - - // Table 6.3.1.1.2-1 in 38.212 - switch(rank){ - case 1: - if(n2>1) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; - } - else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 4; - } - } - else{ - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 4; - } - } - break; - case 2: - if(n1*n2 == 2) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; - } - *x1 += 1; - } - else { - if(n2>1) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 3; - } - else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 3; - } - } - else{ - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; - } - } - *x1 += 2; - } - break; - case 3: - case 4: - if(n1*n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - if(n1*n2 >= 8) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; - } - } - break; - case 5: - case 6: - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - break; - case 7: - case 8: - if(n1 == 4 && n2 == 1) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - if(n1 > 2 && n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - } - break; - default: - AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n"); - } -} - - -void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - for(int i=0; i<8; i++) { - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0; - if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) - return; - else { - if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) { - if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { - if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present == - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { - csi_report->N1 = 1; - csi_report->N2 = 1; - if (i==0) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2; - if (i==1) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1; - } - else { // more than two - int n1,n2,o1,o2,x1,x2; - get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo); - get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode); - csi_report->N1 = n1; - csi_report->N2 = n2; - csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode; - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2; - } - } - else - AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n"); - } - else - AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n"); - } - } -} - -void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration; - - if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) { - for(int i=0; i<8; i++) { - if ((ri_restriction>>i)&0x01) { - csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4; - if(codebookConfig != NULL) { - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){ - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) { - if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present > - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { - // more than 4 antenna ports - if (i > 4) - csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB - } - } - } - } - } - else - csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0; - } - } - else - AssertFatal(1==0,"Sub-band CQI reporting not yet supported"); -} - -//!TODO : same function can be written to handle csi_resources -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){ - uint8_t csi_report_id = 0; - uint8_t nb_resources = 0; - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; - NR_CSI_ResourceConfigId_t csi_ResourceConfigId; - struct NR_CSI_ResourceConfig *csi_resourceconfig; - - // for each CSI measurement report configuration (list of CSI-ReportConfig) - LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count); - for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ - struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - // MAC structure for CSI measurement reports (per UE and per report) - nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; - // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration - // (either CSI-RS or SSB) - csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; - // looking for CSI-ResourceConfig - int found_resource = 0; - int csi_resourceidx = 0; - while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) { - csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; - if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) - found_resource = 1; - csi_resourceidx++; - } - AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n", - csi_ResourceConfigId); - - long resourceType = csi_resourceconfig->resourceType; - - reportQuantity_type = csi_reportconfig->reportQuantity.present; - csi_report->reportQuantity_type = reportQuantity_type; - - // setting the CSI or SSB index list - if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { - for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) { - if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId == - *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ - //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; - csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array; - csi_report->CSI_Index_list = NULL; - break; - } - } - } - else { - if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) { - AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL, - "Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n"); - for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { - if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == - *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { - //For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 - nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count; - csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array; - csi_report->SSB_Index_list = NULL; - break; - } - } - } - else AssertFatal(1==0,"Only periodic resource configuration currently supported\n"); - } - LOG_D(NR_MAC,"nb_resources %d\n",nb_resources); - // computation of bit length depending on the report type - switch(reportQuantity_type){ - case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP): - compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP): - compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - default: - AssertFatal(1==0,"Not yet supported CSI report quantity type"); - } - } -} - - -uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE, - uint8_t csi_report_id) { - - uint16_t csi_bitlen = 0; - uint16_t max_bitlen = 0; - L1_RSRP_bitlen_t * CSI_report_bitlen = NULL; - CSI_Meas_bitlen_t * csi_meas_bitlen = NULL; - - if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type|| - NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){ - CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements - csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + - CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * - (CSI_report_bitlen->nb_ssbri_cri -1 ))); - } else{ - csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements - uint16_t temp_bitlen; - for (int i=0; i<8; i++) { - temp_bitlen = (csi_meas_bitlen->cri_bitlen+ - csi_meas_bitlen->ri_bitlen+ - csi_meas_bitlen->li_bitlen[i]+ - csi_meas_bitlen->cqi_bitlen[i]+ - csi_meas_bitlen->pmi_x1_bitlen[i]+ - csi_meas_bitlen->pmi_x2_bitlen[i]); - if(temp_bitlen>max_bitlen) - max_bitlen = temp_bitlen; - } - csi_bitlen += max_bitlen; - } - - return csi_bitlen; -} - - void nr_csi_meas_reporting(int Mod_idP, frame_t frame, sub_frame_t slot) { - NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - - UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) { - const NR_CellGroupConfig_t *CellGroup = UE->CellGroup; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { continue; } - if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated || - !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue; - const NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; + if (!csi_measconfig) continue; AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0, "NO CSI report configuration available"); - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (CellGroup && - CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; @@ -760,14 +212,9 @@ void nr_csi_meas_reporting(int Mod_idP, curr_pucch->frame = frame; curr_pucch->ul_slot = sched_slot; curr_pucch->resource_indicator = res_index; - curr_pucch->csi_bits += nr_get_csi_bitlen(UE,csi_report_id); + curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id); - const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - - int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + int bwp_start = ul_bwp->BWPStart; // going through the list of PUCCH resources to find the one indexed by resource_id uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; @@ -824,16 +271,9 @@ static void handle_dl_harq(NR_UE_info_t * UE, add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); harq->round = 0; harq->ndi ^= 1; - } else if (harq->round >= harq_round_max - 1) { - add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); - harq->round = 0; - harq->ndi ^= 1; - - NR_mac_stats_t *stats = &UE->mac_stats; - stats->dl.errors++; - LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, stats->dl.errors); - + abort_nr_dl_harq(UE, harq_pid); + LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors); } else { LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti); add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid); @@ -842,13 +282,13 @@ static void handle_dl_harq(NR_UE_info_t * UE, } int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; - NR_TCI_State_t *tci =NULL; - int i; - for(i=0; ispCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config; + int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0; + NR_TCI_State_t *tci =NULL; + + for(int i=0; itci_StatesToAddModList->list.array[i]; if(tci != NULL) { if(tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { @@ -868,18 +308,17 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * } int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup ; - int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; + NR_TCI_State_t *tci =NULL; NR_TCI_StateId_t *tci_id = NULL; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; - int i; int flag = 0; int tci_stateID = -1; - - for(i=0; ispCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config; + int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0; + for(int i=0; itci_StatesToAddModList->list.array[i]; if(tci != NULL && tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) { @@ -935,21 +374,12 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { uint8_t target_ssb_beam_index = curr_ssb_beam_index; uint8_t is_triggering_ssb_beam_switch =0; uint8_t ssb_idx = 0; - int pdsch_bwp_id =0; + int pdsch_bwp_id = 0; int ssb_index[MAX_NUM_SSB] = {0}; int ssb_rsrp[MAX_NUM_SSB] = {0}; uint8_t idx = 0; - + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - - //bwp indicator - int n_dl_bwp=0; - if (CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) - n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; uint8_t nr_ssbri_cri = 0; uint8_t nb_of_csi_ssb_report = UE->csi_report_template[cqi_idx].nb_of_csi_ssb_report; @@ -957,6 +387,9 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { uint8_t diff_rsrp_idx = 0; uint8_t i, j; + //bwp indicator + int n_dl_bwp = dl_bwp->n_dl_bwp; + const int bwp_id = dl_bwp->bwp_id; if (n_dl_bwp < 4) pdsch_bwp_id = bwp_id; else @@ -1183,7 +616,6 @@ void evaluate_rsrp_report(NR_UE_info_t *UE, stats->num_rsrp_meas++; } - void evaluate_cri_report(uint8_t *payload, uint8_t cri_bitlen, int cumul_bits, @@ -1219,9 +651,11 @@ void evaluate_cqi_report(uint8_t *payload, nr_csi_report_t *csi_report, int cumul_bits, uint8_t ri, - NR_UE_sched_ctrl_t *sched_ctrl, + NR_UE_info_t *UE, long *cqi_Table){ + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + //TODO sub-band CQI report not yet implemented int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[ri]; @@ -1244,7 +678,7 @@ void evaluate_cqi_report(uint8_t *payload, // TODO for wideband case and multiple TB const int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb; - const int mcs_table = sched_ctrl->pdsch_semi_static.mcsTableIdx; + const int mcs_table = UE->current_DL_BWP.mcsTableIdx; const int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table; sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_table, cqi_idx); } @@ -1319,11 +753,12 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_ServingCellConfigCommon_t *scc) { /** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */ - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload; uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; int cumul_bits = 0; int r_index = -1; for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) { @@ -1358,7 +793,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, cumul_bits += ri_bitlen; if (r_index != -1) skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen); - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; @@ -1374,7 +809,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl); sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id; cumul_bits += pmi_bitlen; - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; @@ -1392,7 +827,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl); sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id; cumul_bits += pmi_bitlen; - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; default: AssertFatal(1==0, "Invalid or not supported CSI measurement report\n"); @@ -1462,7 +897,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; - NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max); + NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (!harq) { LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); break; @@ -1471,7 +906,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); - handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max); + handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++; } } @@ -1502,15 +937,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); return; } - AssertFatal(UE->CellGroup,"Cellgroup is null for UE %04x\n", uci_234->rnti); - AssertFatal(UE->CellGroup->spCellConfig, - "Cellgroup->spCellConfig is null for UE %04x\n", uci_234->rnti); - AssertFatal(UE->CellGroup->spCellConfig->spCellConfigDedicated, - "Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %04x\n", uci_234->rnti); - if ( UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL) - return; - NR_CSI_MeasConfig_t *csi_MeasConfig = UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_CSI_MeasConfig_t *csi_MeasConfig = UE->current_UL_BWP.csi_MeasConfig; + if (csi_MeasConfig==NULL) + return; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; // tpc (power control) @@ -1524,13 +954,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; - NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max); + NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (!harq) break; DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max); + handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max); } } if ((uci_234->pduBitmap >> 2) & 0x01) { @@ -1599,7 +1029,6 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, return true; } - // this function returns an index to NR_sched_pucch structure // currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1 // if the function returns -1 it was not possible to schedule acknack @@ -1613,7 +1042,8 @@ int nr_acknack_scheduling(int mod_id, const int CC_id = 0; const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch; const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || RC.nrmac[mod_id]->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; @@ -1628,23 +1058,10 @@ int nr_acknack_scheduling(int mod_id, * later) * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_CellGroupConfig_t *cg = UE->CellGroup; + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - pucch_Config = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } - NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? - &sched_ctrl->active_ubwp->bwp_Common->genericParameters: - &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int bwp_start = ul_bwp->BWPStart; + int bwp_size = ul_bwp->BWPSize; NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; LOG_D(NR_MAC, "In %s: %4d.%2d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c); @@ -1668,7 +1085,7 @@ int nr_acknack_scheduling(int mod_id, && csi_pucch->csi_bits > 0 && csi_pucch->frame == f && csi_pucch->ul_slot == s)) - nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); + nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; @@ -1699,22 +1116,13 @@ int nr_acknack_scheduling(int mod_id, LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c); - // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP - NR_BWP_UplinkDedicated_t *ubwpd=NULL; + nr_dci_format_t dci_format = NR_DL_DCI_FORMAT_1_0; + if(is_common == 0) + dci_format = UE->current_DL_BWP.dci_format; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) - ubwpd = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - - NR_SearchSpace__searchSpaceType_PR ss_type = (is_common==0 && (sched_ctrl->active_bwp || ubwpd)) ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common; uint8_t pdsch_to_harq_feedback[8]; - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - int max_fb_time = 0; - get_pdsch_to_harq_feedback(UE, bwp_id, ss_type, &max_fb_time, pdsch_to_harq_feedback); + get_pdsch_to_harq_feedback(pucch_Config, dci_format, &max_fb_time, pdsch_to_harq_feedback); LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c); /* there is a HARQ. Check whether we can use it for this ACKNACK */ @@ -1735,13 +1143,12 @@ int nr_acknack_scheduling(int mod_id, // we cannot reach this timing anymore, allocate and try again const int f = pucch->frame; const int s = pucch->ul_slot; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; LOG_D(NR_MAC, "In %s: %4d.%2d DAI > 0, cannot reach timing for pucch in %4d.%2d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s); if (!(csi_pucch && csi_pucch->csi_bits > 0 && csi_pucch->frame == f && csi_pucch->ul_slot == s)) - nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); + nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; if(((s + 1)%nr_slots_period) == 0) @@ -1840,10 +1247,10 @@ int nr_acknack_scheduling(int mod_id, csi_pucch->ul_slot == pucch->ul_slot) { // skip the CSI PUCCH if it is present and if in the next frame/slot // and if we don't multiplex - // FIXME currently we support at most 11 bits in pucch2 so skip also in that case + /* FIXME currently we support at most 11 bits in pucch2 so skip also in that case. + We need to set the limit to 10 because SR scheduling has been moved afterwards */ if(!csi_pucch->simultaneous_harqcsi - || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) { - + || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 10)) { LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot); nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE); memset(csi_pucch, 0, sizeof(*csi_pucch)); @@ -1863,9 +1270,7 @@ int nr_acknack_scheduling(int mod_id, else { csi_pucch->timing_indicator = ind_found; csi_pucch->dai_c++; - // keep updating format 2 indicator - pucch->timing_indicator = ind_found; // index in the list of timing indicators - pucch->dai_c++; + memset(pucch,0,sizeof(*pucch)); LOG_D(NR_MAC,"multiplexing csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot); return 1; @@ -1898,31 +1303,20 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) { if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) return; - NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + UE_iterator(nrmac->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; + if (sched_ctrl->ul_failure==1 || sched_ctrl->rrc_processing_timer>0) continue; + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; - if (sched_ctrl->ul_failure==1) continue; - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (UE->CellGroup && - UE->CellGroup->spCellConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } - - else continue; - if (!pucch_Config->schedulingRequestResourceToAddModList) - continue; + if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) + continue; AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available"); - for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { + for (int SR_resource_id = 0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; int SR_period; int SR_offset; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fe921a6d2a..43e88eb9a9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -37,14 +37,7 @@ #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" -int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) { - - int dci_format = sched_ctrl->search_space && sched_ctrl->search_space->searchSpaceType && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ? - NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - - return(dci_format); -} +//#define SRS_IND_DEBUG const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) { @@ -319,52 +312,51 @@ int nr_process_mac_pdu( instance_t module_idP, mac_len = 6; } - nr_mac_rrc_data_ind(module_idP, - CC_id, - frameP, - 0, - 0, - UE->rnti, - CCCH, - pduP + mac_subheader_len, - mac_len, - 0); + send_initial_ul_rrc_message(module_idP, + CC_id, + UE, + CCCH, + pduP + mac_subheader_len, + mac_len); break; case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28): // check if LCID is valid at current time. - if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) - return 0; + if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) { + return 0; + } - LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n", - UE->rnti, - frameP, - slot, - rx_lcid<4?"DCCH":"DTCH", - rx_lcid, - module_idP, - mac_len); - UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len; + LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n", + UE->rnti, + frameP, + slot, + rx_lcid<4?"DCCH":"DTCH", + rx_lcid, + module_idP, + mac_len); + UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len; - mac_rlc_data_ind(module_idP, - UE->rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *)(pduP + mac_subheader_len), - mac_len, - 1, - NULL); + mac_rlc_data_ind(module_idP, + UE->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *)(pduP + mac_subheader_len), + mac_len, + 1, + NULL); - /* Updated estimated buffer when receiving data */ - if (sched_ctrl->estimated_ul_buffer >= mac_len) - sched_ctrl->estimated_ul_buffer -= mac_len; - else - sched_ctrl->estimated_ul_buffer = 0; - break; + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_len) { + sched_ctrl->estimated_ul_buffer -= mac_len; + } else { + sched_ctrl->estimated_ul_buffer = 0; + } + + break; default: LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); @@ -399,7 +391,7 @@ int nr_process_mac_pdu( instance_t module_idP, return 0; } -void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid) +void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; @@ -449,7 +441,7 @@ void handle_nr_ul_harq(const int CC_idP, remove_front_nr_list(&sched_ctrl->feedback_ul_harq); sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false; - if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) { + if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); } else { sched_ctrl->ul_harq_processes[harq_pid].round++; @@ -470,7 +462,7 @@ void handle_nr_ul_harq(const int CC_idP, harq_pid, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); - } else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) { + } else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); LOG_D(NR_MAC, "RNTI %04x: Ulharq id %d crc failed in all rounds\n", @@ -543,7 +535,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, else{ LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti); UE_scheduling_control->tpc0 = 1; - } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) @@ -746,14 +737,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, return; } - if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) { - LOG_D(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); + if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) { + LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; } - LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); ra->msg3_round++; @@ -762,23 +752,64 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } -long get_K2(NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfigCommonSIB_t *scc_sib1, - NR_BWP_Uplink_t *ubwp, +void handle_nr_srs_measurements(const module_id_t module_id, + const frame_t frame, + const sub_frame_t slot, + const rnti_t rnti, + const uint16_t timing_advance, + 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) { + + LOG_D(NR_MAC, "(%d.%d) Received SRS indication for rnti: 0x%04x\n", frame, slot, rnti); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "frame = %i\n", frame); + LOG_I(NR_MAC, "slot = %i\n", slot); + 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, "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); + } +#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); + return; + } + + 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; + + 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)); + 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) { + ulprbbl[rb] = 0x3FFF; // all symbols taken + } + LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); + } +} + +long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu) { - NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = NULL; - if(ubwp) { - tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } else if(scc) { - tda_list = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } else if(scc_sib1) { - tda_list = scc_sib1->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } + NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment]; - if (tda_list->k2) - return *tda_list->k2; + if (tda->k2) + return *tda->k2; else if (mu < 2) return 1; else if (mu == 2) @@ -793,10 +824,8 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int now = frame * n + slot; - const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl; - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; int num_slots_per_period; @@ -842,40 +871,22 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, const int CC_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch; - NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - (NR_ServingCellConfigCommon_t *)scc, - sib1); int rbStart = 0; // wrt BWP start - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = UE->current_UL_BWP.BWPSize; const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); - LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, tbs %d\n",num_dmrs_cdm_grps_no_data, retInfo->tb_size); + 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; - int dci_format = get_dci_format(sched_ctrl); - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } @@ -891,14 +902,9 @@ 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; - int dci_format = get_dci_format(sched_ctrl); - nr_set_pusch_semi_static(sib1, + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, &temp_ps); /* the retransmission will use a different time domain allocation, check @@ -993,13 +999,13 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, return true; } -void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static_t *ps) -{ - const int mcs = sched_pusch->mcs; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); +void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_PUSCH_Config_t *pusch_Config, const int mcs_table) { - if (ps->pusch_Config && ps->pusch_Config->tp_pi2BPSK && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + const int mcs = sched_pusch->mcs; + sched_pusch->R = nr_get_code_rate_ul(mcs, mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, mcs_table); + + if (pusch_Config && pusch_Config->tp_pi2BPSK && ((mcs_table == 3 && mcs < 2) || (mcs_table == 4 && mcs < 6))) { sched_pusch->R >>= 1; sched_pusch->Qm <<= 1; } @@ -1018,7 +1024,7 @@ static int comparator(const void *p, const void *q) { void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, - NR_UE_info_t *UE_list[], + NR_UE_info_t *UE_list[], int max_num_ue, int n_rb_sched, uint16_t *rballoc_mask) { @@ -1042,18 +1048,11 @@ void pf_ul(module_id_t module_id, LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; int rbStart = 0; // wrt BWP start - NR_CellGroupConfig_t *cg = UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + 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; @@ -1079,10 +1078,11 @@ void pf_ul(module_id_t module_id, /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; + // we have filled all with mandatory retransmissions + // no need to schedule new transmissions if (remainUEs == 0) - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - return; + return; + continue; } const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); @@ -1090,12 +1090,16 @@ void pf_ul(module_id_t module_id, const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity); LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no"); - if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) + if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) { continue; - + } + const NR_bler_options_t *bo = &nrmac->ul_bler; const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */ - sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame); + if (bo->harq_round_max == 1) + sched_pusch->mcs = max_mcs; + else + sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame); /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled * based on data to transmit) */ @@ -1105,12 +1109,12 @@ void pf_ul(module_id_t module_id, const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; + // for now taking the lowest value among the available aggregation levels + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space, + 1<0) break; } int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], CC_id, @@ -1119,38 +1123,31 @@ void pf_ul(module_id_t module_id, &sched_ctrl->sched_pdcch, sched_ctrl->coreset, Y); - + if (CCEIndex<0) { - LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti); - continue; + LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti); + continue; } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; - + + // we have filled all with mandatory retransmissions + // no need to schedule new transmissions if (remainUEs == 0) - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - return; + 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 dci_format, TDA, or + * 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 uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(current_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } @@ -1175,7 +1172,7 @@ void pf_ul(module_id_t module_id, NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs); - update_ul_ue_R_Qm(sched_pusch, ps); + update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table); sched_pusch->rbStart = rbStart; sched_pusch->rbSize = min_rb; sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, @@ -1198,7 +1195,7 @@ void pf_ul(module_id_t module_id, /* Create UE_sched for UEs eligibale for new data transmission*/ /* Calculate coefficient*/ - const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs]; + const uint32_t tbs = ul_pf_tbs[current_BWP->mcs_table][sched_pusch->mcs]; float coeff_ue = (float) tbs / UE->ul_thr_ue; LOG_D(NR_MAC,"rnti %04x b %d, ul_thr_ue %f, tbs %d, coeff_ue %f\n", UE->rnti, b, UE->ul_thr_ue, tbs, coeff_ue); @@ -1225,7 +1222,7 @@ void pf_ul(module_id_t module_id, sched_ctrl->search_space, 1<0) - break; + break; } int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], CC_id, @@ -1241,44 +1238,29 @@ void pf_ul(module_id_t module_id, } else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, iterator->UE->rnti); - NR_CellGroupConfig_t *cg = iterator->UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated - && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - - int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0; - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + 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 dci_format, TDA, or + * 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 uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(current_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } - update_ul_ue_R_Qm(sched_pusch, ps); + update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table); + int rbStart = 0; const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; @@ -1326,8 +1308,8 @@ void pf_ul(module_id_t module_id, 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] ^= slbitmap; + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; iterator++; @@ -1344,11 +1326,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n"); - const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing : - scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; - + // no UEs if (nr_mac->UE_info.list[0] == NULL) - // no UEs return false; const int CC_id = 0; @@ -1358,14 +1337,16 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t * TDAs yet). If the TDA is negative, it means that there is no UL slot to * schedule now (slot + k2 is not UL slot) */ NR_UE_sched_ctrl_t *sched_ctrl = &nr_mac->UE_info.list[0]->UE_sched_ctrl; + NR_UE_UL_BWP_t *current_BWP = &nr_mac->UE_info.list[0]->current_UL_BWP; + int mu = current_BWP->scs; const int temp_tda = get_ul_tda(nr_mac, scc, slot); - int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, temp_tda, mu); + int K2 = get_K2(current_BWP->tdaList, temp_tda, mu); const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_slot); if (tda < 0) return false; - DevAssert(K2 == get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, tda, mu)); + DevAssert(K2 == get_K2(current_BWP->tdaList, tda, mu)); if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; @@ -1379,7 +1360,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot); // FIXME: Avoid mixed slots for initialUplinkBWP - if (sched_ctrl->active_ubwp==NULL && is_mixed_slot) + if (current_BWP->bwp_id==0 && is_mixed_slot) return false; // Avoid slots with the SRS @@ -1394,9 +1375,9 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t sched_ctrl->sched_pusch.frame = sched_frame; UE_iterator(nr_mac->UE_info.list, UE2) { NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl; - AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), + AssertFatal(K2 == get_K2(current_BWP->tdaList, tda, mu), "Different K2, %d(UE%d) != %ld(UE%04x)\n", - K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti); + K2, 0, get_K2(current_BWP->tdaList, tda, mu), UE2->rnti); sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; } @@ -1407,24 +1388,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); + const uint16_t bwpSize = current_BWP->BWPSize; + const uint16_t bwpStart = current_BWP->BWPStart; - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - const uint16_t bwpStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - - NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if (sched_ctrl->active_ubwp) { - tdaList = sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if (scc) { - tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1; - tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + const int startSymbolAndLength = current_BWP->tdaList->list.array[tda]->startSymbolAndLength; int startSymbolIndex, nrOfSymbols; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); const uint16_t symb = SL_to_bitmap(startSymbolIndex, nrOfSymbols); @@ -1524,10 +1491,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; UE->mac_stats.ul.current_bytes = 0; @@ -1573,7 +1537,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Statistics */ - AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); + 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]++; if (cur_harq->round == 0) { UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size; @@ -1619,7 +1583,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) sched_pusch->tb_size, harq_id, cur_harq->round, - nr_rv_round_map[cur_harq->round], + nr_rv_round_map[cur_harq->round%4], cur_harq->ndi, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, @@ -1653,23 +1617,20 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->handle = 0; //not yet used /* FAPI: BWP */ - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - pusch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pusch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pusch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing; + pusch_pdu->bwp_size = current_BWP->BWPSize; + pusch_pdu->bwp_start = current_BWP->BWPStart; + pusch_pdu->subcarrier_spacing = current_BWP->scs; pusch_pdu->cyclic_prefix = 0; /* FAPI: PUSCH information always included */ pusch_pdu->target_code_rate = sched_pusch->R; pusch_pdu->qam_mod_order = sched_pusch->Qm; pusch_pdu->mcs_index = sched_pusch->mcs; - pusch_pdu->mcs_table = ps->mcs_table; - pusch_pdu->transform_precoding = ps->transform_precoding; - if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) - pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; + pusch_pdu->mcs_table = current_BWP->mcs_table; + pusch_pdu->transform_precoding = current_BWP->transform_precoding; + if (current_BWP->pusch_Config && current_BWP->pusch_Config->dataScramblingIdentityPUSCH) + pusch_pdu->data_scrambling_id = *current_BWP->pusch_Config->dataScramblingIdentityPUSCH; else pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = ps->nrOfLayers; @@ -1705,7 +1666,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->rb_start = sched_pusch->rbStart; pusch_pdu->rb_size = sched_pusch->rbSize; pusch_pdu->vrb_to_prb_mapping = 0; - if (ps->pusch_Config==NULL || ps->pusch_Config->frequencyHopping==NULL) + if (current_BWP->pusch_Config==NULL || current_BWP->pusch_Config->frequencyHopping==NULL) pusch_pdu->frequency_hopping = 0; else pusch_pdu->frequency_hopping = 1; @@ -1715,8 +1676,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->nr_of_symbols = ps->nrOfSymbols; /* PUSCH PDU */ - AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round); - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; + 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); + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round%4]; pusch_pdu->pusch_data.harq_process_id = harq_id; pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size; @@ -1739,7 +1700,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) else AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); - LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, ps->mcs_table); + LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, current_BWP->mcs_table); } /*-----------------------------------------------------------------------------*/ @@ -1763,9 +1724,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) /* look up the PDCCH PDU for this BWP and CORESET. If it does not exist, * create it */ - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - NR_SearchSpace_t *ss = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->search_space: RC.nrmac[module_id]->sched_ctrlCommon->search_space; - NR_ControlResourceSet_t *coreset = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->coreset: RC.nrmac[module_id]->sched_ctrlCommon->coreset; + NR_SearchSpace_t *ss = sched_ctrl->search_space; + NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = pdcch_pdu_coreset[coresetid]; if (!pdcch_pdu) { @@ -1775,7 +1735,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch); + nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); pdcch_pdu_coreset[coresetid] = pdcch_pdu; } @@ -1800,35 +1760,24 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); - int n_ubwp=1; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) { - n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; - } config_uldci(sib1, - sched_ctrl->active_ubwp, - ubwpd, scc, pusch_pdu, &uldci_payload, - ps->dci_format, ps->time_domain_allocation, UE->UE_sched_ctrl.tpc0, - n_ubwp, - bwp_id); + current_BWP); fill_dci_pdu_rel15(scc, cg, + &UE->current_DL_BWP, dci_pdu, &uldci_payload, - ps->dci_format, + current_BWP->dci_format, rnti_types[0], pusch_pdu->bwp_size, - bwp_id, - coresetid, + current_BWP->bwp_id, + coreset, nr_mac->cset0_bwp_size); memset(sched_pusch, 0, sizeof(*sched_pusch)); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7911275f70..674d80a4d4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -36,12 +36,9 @@ void set_cset_offset(uint16_t); -void mac_top_init_gNB(void); - -void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl); +void mac_top_init_gNB(ngran_node_t node_type); void config_common(int Mod_idP, - int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc); @@ -52,7 +49,6 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, uint32_t rrc_reconfiguration_delay); int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, int sib1_tda, @@ -95,7 +91,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, int nrOfSymbols, uint16_t dlDmrsSymbPos, uint8_t candidate_idx, - int num_total_bytes); + uint16_t num_total_bytes); /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id); @@ -134,7 +130,6 @@ int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slo void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Uplink_t *ubwp, sub_frame_t current_subframe, frame_t current_frame, NR_RA_t *ra, @@ -192,18 +187,14 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, void config_uldci(const NR_SIB1_t *sib1, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int dci_format, int time_domain_assignment, uint8_t tpc, - int n_ubwp, - int bwp_id); + NR_UE_UL_BWP_t *ul_bwp); -void nr_schedule_pucch(gNB_MAC_INST* nrmac, +void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); @@ -218,16 +209,15 @@ void nr_csi_meas_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); -int nr_acknack_scheduling( int Mod_idP, - NR_UE_info_t * UE, - frame_t frameP, - sub_frame_t slotP, - int r_pucch, - int do_common); +int nr_acknack_scheduling(int Mod_idP, + NR_UE_info_t *UE, + frame_t frameP, + sub_frame_t slotP, + int r_pucch, + int do_common); -void get_pdsch_to_harq_feedback(NR_UE_info_t *, - int bwp_id, - NR_SearchSpace__searchSpaceType_PR ss_type, +void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, + nr_dci_format_t dci_format, int *max_fb_time, uint8_t *pdsch_to_harq_feedback); @@ -251,17 +241,12 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, */ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, + NR_PUCCH_Config_t *pucch_Config, int CCEIndex); -void nr_configure_pucch(const NR_SIB1_t *sib1, - nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *CellGroup, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, - uint16_t rnti, + NR_UE_info_t* UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, @@ -274,7 +259,7 @@ void find_search_space(int ss_type, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, - NR_BWP_t *bwp, + bool is_sib1, NR_sched_pdcch_t *pdcch); NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, @@ -300,19 +285,21 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *dl_bwp, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_formats, int rnti_types, int N_RB, int bwp_id, - NR_ControlResourceSetId_t coreset_id, + NR_ControlResourceSet_t *coreset, uint16_t cset0_bwp_size); void prepare_dci(const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *dl_bwp, + const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, - nr_dci_format_t format, - int bwp_id); + nr_dci_format_t format); void set_r_pucch_parms(int rsetindex, int r_pucch, @@ -322,18 +309,6 @@ void set_r_pucch_parms(int rsetindex, int *nr_of_symbols, int *start_symbol_index); -NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - -NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - -NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp, - const NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - /* find coreset within the search space */ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, @@ -342,34 +317,24 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_SearchSpace__searchSpaceType_PR ss_type); /* find a search space within a BWP */ -NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1, - NR_ServingCellConfigCommon_t *scc, +NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, NR_SearchSpace__searchSpaceType_PR target_ss); -long get_K2(NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfigCommonSIB_t *scc_sib1, - NR_BWP_Uplink_t *ubwp, +long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu); -void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *secondaryCellGroup, - const NR_BWP_Downlink_t *bwp, - const NR_BWP_DownlinkDedicated_t *bwpd0, int tda, uint8_t layers, NR_UE_sched_ctrl_t *sched_ctrl, NR_pdsch_semi_static_t *ps); -void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, - long dci_format, int tda, - uint8_t num_dmrs_cdm_grps_no_data, uint8_t nrOfLayers, NR_pusch_semi_static_t *ps); @@ -404,7 +369,13 @@ NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP); int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); -NR_UE_info_t*add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); +void configure_UE_BWP(gNB_MAC_INST *nr_mac, + NR_ServingCellConfigCommon_t *scc, + NR_UE_sched_ctrl_t *sched_ctrl, + NR_RA_t *ra, + NR_UE_info_t *UE); + +NR_UE_info_t* add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti); @@ -412,24 +383,12 @@ void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti); int nr_get_default_pucch_res(int pucch_ResourceCommon); -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE); - int get_dlscs(nfapi_nr_config_request_t *cfg); int get_ulscs(nfapi_nr_config_request_t *cfg); int get_symbolsperslot(nfapi_nr_config_request_t *cfg); -void config_nr_mib(int Mod_idP, - int CC_idP, - int p_gNBP, - int subCarrierSpacingCommon, - uint32_t ssb_SubcarrierOffset, - int dmrs_TypeA_Position, - uint32_t pdcch_ConfigSIB1, - int cellBarred, - int intraFreqReselection); - int nr_write_ce_dlsch_pdu(module_id_t module_idP, const NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *mac_pdu, @@ -446,7 +405,7 @@ int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id); +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id); /* \brief Function to indicate a received SDU on ULSCH. @@ -482,9 +441,19 @@ void handle_nr_ul_harq(const int CC_idP, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu); +void handle_nr_srs_measurements(const module_id_t module_id, + const frame_t frame, + const sub_frame_t slot, + const rnti_t rnti, + const uint16_t timing_advance, + 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); + int16_t ssb_index_from_prach(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP, + sub_frame_t slotP, uint16_t preamble_index, uint8_t freq_index, uint8_t symbol); @@ -503,7 +472,6 @@ 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); -int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl); 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); @@ -526,10 +494,21 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, int max_mcs, frame_t frame); +void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid); + void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp); void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl); +void send_initial_ul_rrc_message(module_id_t module_id, + int CC_id, + const NR_UE_info_t *UE, + rb_id_t srb_id, + const uint8_t *sdu, + sdu_size_t sdu_len); + +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c new file mode 100644 index 0000000000..578e4fb453 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -0,0 +1,131 @@ +/* + * 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 + */ + +#include "mac_rrc_dl_handler.h" + +#include "mac_proto.h" +#include "openair2/RRC/NR/rrc_gNB_UE_context.h" + +#include "NR_RRCSetup.h" +#include "NR_DL-CCCH-Message.h" +#include "NR_CellGroupConfig.h" + +int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc, NR_RRCSetup_t *rrcSetup); + +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* dispatch message to dl_rrc_message_rrcSetup() and others, similar to as is + * done in the DU (should be the same here) */ + + if (dl_rrc->srb_id == 0) { + + NR_DL_CCCH_Message_t *dl_ccch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **) &dl_ccch_msg, + dl_rrc->rrc_container, + dl_rrc->rrc_container_length, + 0, + 0); + AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n"); + + switch (dl_ccch_msg->message.choice.c1->present) { + case NR_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_W(NR_MAC, "Received NOTHING on DL-CCCH-Message\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_rrcReject: + LOG_D(NR_MAC, "DL-CCCH/SRB0, received rrcReject for RNTI %04x\n", dl_rrc->rnti); + AssertFatal(0, "rrcReject not implemented yet\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: + LOG_I(NR_MAC, "DL-CCCH/SRB0, received rrcSetup for RNTI %04x\n", dl_rrc->rnti); + return dl_rrc_message_rrcSetup(module_id, dl_rrc, dl_ccch_msg->message.choice.c1->choice.rrcSetup); + break; + case NR_DL_CCCH_MessageType__c1_PR_spare2: + LOG_W(NR_MAC, "DL-CCCH/SRB0, received spare2\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_spare1: + LOG_W(NR_MAC, "DL-CCCH/SRB0, received spare1\n"); + break; + default: + AssertFatal(0 == 1, "Unknown DL-CCCH/SRB0 message %d\n", dl_ccch_msg->message.choice.c1->present); + break; + } + return 0; + } + + return -1; /* not handled yet */ +} + +int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc, NR_RRCSetup_t *rrcSetup) +{ + DevAssert(rrcSetup != NULL); + + NR_RRCSetup_IEs_t *rrcSetup_ies = rrcSetup->criticalExtensions.choice.rrcSetup; + AssertFatal(rrcSetup_ies->masterCellGroup.buf != NULL,"masterCellGroup is NULL\n"); + NR_CellGroupConfig_t *cellGroup = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroup, + rrcSetup_ies->masterCellGroup.buf, + rrcSetup_ies->masterCellGroup.size, + 0, + 0); + AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n"); + + /* there might be a memory leak for the cell group if we call this multiple + * times. Also, the first parameters of rrc_mac_config_req_gNB() are only + * relevant when setting the scc, which we don't do (and cannot do) here. */ + rrc_pdsch_AntennaPorts_t pap = {0}; + rrc_mac_config_req_gNB(module_id, + pap, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + NULL, /* scc */ + NULL, /* mib */ + NULL, /* sib1 */ + 0, /* add_ue */ + dl_rrc->rnti, + cellGroup); + + /* TODO: drop the RRC context */ + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti); + gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + ue_context_p->ue_context.SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList; + ue_context_p->ue_context.masterCellGroup = cellGroup; + + /* TODO: this should pass through RLC and NOT the RRC with a shared buffer */ + AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); + memcpy(ue_p->Srb0.Tx_buffer.Payload, dl_rrc->rrc_container, dl_rrc->rrc_container_length); + ue_p->Srb0.Tx_buffer.payload_size = dl_rrc->rrc_container_length; + + protocol_ctxt_t ctxt = { .module_id = module_id, .rnti = dl_rrc->rnti }; + nr_rrc_rlc_config_asn1_req(&ctxt, + ue_context_p->ue_context.SRB_configList, + NULL, + NULL, + NULL, + cellGroup->rlc_BearerToAddModList); + + return 0; +} diff --git a/openair2/COMMON/itti_sim_messages_def.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h similarity index 59% rename from openair2/COMMON/itti_sim_messages_def.h rename to openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 681fc932dd..ecbc95eef0 100644 --- a/openair2/COMMON/itti_sim_messages_def.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -19,18 +19,12 @@ * contact@openairinterface.org */ -/*! \file itti_sim_messages_def.h - * \brief itti message for itti simulator - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ +#ifndef MAC_RRC_DL_HANDLER_H +#define MAC_RRC_DL_HANDLER_H +#include "platform_types.h" +#include "f1ap_messages_types.h" +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); -MESSAGE_DEF(GNB_RRC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBBCCHind) -MESSAGE_DEF(GNB_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBCCCHind) -MESSAGE_DEF(GNB_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBDCCHind) -MESSAGE_DEF(UE_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UECCCHind) -MESSAGE_DEF(UE_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UEDCCHind) +#endif /* MAC_RRC_DL_HANDLER_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h new file mode 100644 index 0000000000..cb80ba4fa5 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -0,0 +1,34 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef MAC_RRC_UL_H +#define MAC_RRC_UL_H + +#include "platform_types.h" +#include "f1ap_messages_types.h" + +typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc); + +struct nr_mac_rrc_ul_if_s; +void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc); +void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc); + +#endif /* MAC_RRC_UL_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c new file mode 100644 index 0000000000..25ee7feb14 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -0,0 +1,49 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_mac_gNB.h" + +#include "mac_rrc_ul.h" + +static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + /* copy all fields, but reallocate rrc_containers! */ + f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); + *f1ap_msg = *ul_rrc; + + f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); + DevAssert(f1ap_msg->rrc_container); + memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); + f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; + + f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + DevAssert(f1ap_msg->du2cu_rrc_container); + memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; + + itti_send_msg_to_task(TASK_RRC_GNB, module_id, msg); +} + +void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) +{ + mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c new file mode 100644 index 0000000000..65e7f10405 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -0,0 +1,50 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_mac_gNB.h" + +#include "mac_rrc_ul.h" + +static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + /* copy all fields, but reallocate rrc_containers! */ + f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); + *f1ap_msg = *ul_rrc; + + f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); + DevAssert(f1ap_msg->rrc_container); + memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); + f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; + + f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + DevAssert(f1ap_msg->du2cu_rrc_container); + memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; + + itti_send_msg_to_task(TASK_DU_F1, module_id, msg); +} + +void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) +{ + mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; +} + diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 9b9fd4e76c..8c1abf4561 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -84,38 +84,42 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset int num = 1; const char *begin = output; const char *end = output + strlen; - + pthread_mutex_lock(&gNB->UE_info.mutex); UE_iterator(gNB->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_mac_stats_t *stats = &UE->mac_stats; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - output += snprintf(output, end - output, - "UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n", + "UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas), UL-SNR %d dB\n", UE->rnti, num++, sched_ctrl->ph, sched_ctrl->pcmax, avg_rsrp, - stats->num_rsrp_meas); + stats->num_rsrp_meas, + stats->srs_wide_band_snr); output += snprintf(output, end - output, "UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", UE->rnti, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri+1, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); output += snprintf(output, end - output, - "UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", - UE->rnti, - stats->dl.rounds[0], stats->dl.rounds[1], - stats->dl.rounds[2], stats->dl.rounds[3], + "UE %04x: dlsch_rounds ", UE->rnti); + output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]); + for (int i = 1; i < gNB->dl_bler.harq_round_max; i++) + output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]); + + output += snprintf(output, + end - output, + ", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", stats->dl.errors, stats->pucch0_DTX, sched_ctrl->dl_bler_stats.bler, @@ -127,23 +131,27 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset output += snprintf(output, end - output, "UE %04x: dlsch_total_bytes %"PRIu64"\n", - UE->rnti, - stats->dl.total_bytes); + UE->rnti, stats->dl.total_bytes); output += snprintf(output, end - output, - "UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", - UE->rnti, - stats->ul.rounds[0], stats->ul.rounds[1], - stats->ul.rounds[2], stats->ul.rounds[3], + "UE %04x: ulsch_rounds ", UE->rnti); + output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]); + for (int i = 1; i < gNB->ul_bler.harq_round_max; i++) + output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]); + + output += snprintf(output, + end - output, + ", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", stats->ulsch_DTX, stats->ul.errors, sched_ctrl->ul_bler_stats.bler, sched_ctrl->ul_bler_stats.mcs); output += snprintf(output, end - output, - "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", - UE->rnti, - stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); + "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", + UE->rnti, + stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); + for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->dl.lc_bytes[lc_id] > 0) output += snprintf(output, @@ -165,8 +173,25 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset return output - begin; } +static void mac_rrc_init(gNB_MAC_INST *mac, ngran_node_t node_type) +{ + switch (node_type) { + case ngran_gNB_CU: + AssertFatal(1 == 0, "nothing to do for CU\n"); + break; + case ngran_gNB_DU: + mac_rrc_ul_f1ap_init(&mac->mac_rrc); + break; + case ngran_gNB: + mac_rrc_ul_direct_init(&mac->mac_rrc); + break; + default: + AssertFatal(0 == 1, "Unknown node type %d\n", node_type); + break; + } +} -void mac_top_init_gNB(void) +void mac_top_init_gNB(ngran_node_t node_type) { module_id_t i; gNB_MAC_INST *nrmac; @@ -203,6 +228,7 @@ void mac_top_init_gNB(void) RC.nrmac[i]->first_MIB = true; pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL); + uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); if (get_softmodem_params()->phy_test) { RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; @@ -211,8 +237,10 @@ void mac_top_init_gNB(void) RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0); RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0); } - pthread_create(&RC.nrmac[i]->stats_thread,NULL,nrmac_stats_thread,(void*)RC.nrmac[i]); + if (!IS_SOFTMODEM_NOSTATS_BIT) + pthread_create(&RC.nrmac[i]->stats_thread, NULL, nrmac_stats_thread, (void*)RC.nrmac[i]); + mac_rrc_init(RC.nrmac[i], node_type); }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); @@ -232,7 +260,6 @@ void mac_top_init_gNB(void) // Initialize Linked-List for Active UEs for (i = 0; i < RC.nb_nr_macrlc_inst; i++) { - nrmac = RC.nrmac[i]; nrmac->if_inst = NR_IF_Module_init(i); memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info)); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7658441aed..09f3193790 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -46,6 +46,7 @@ #include "targets/ARCH/COMMON/common_lib.h" #include "COMMON/platform_constants.h" #include "common/ran_context.h" +#include "collection/linear_alloc.h" /* RRC */ #include "NR_BCCH-BCH-Message.h" @@ -60,6 +61,7 @@ /* Interface */ #include "nfapi_nr_interface_scf.h" #include "NR_PHY_INTERFACE/NR_IF_Module.h" +#include "mac_rrc_ul.h" /* MAC */ #include "LAYER2/MAC/mac.h" @@ -75,7 +77,6 @@ #define MAX_NUM_BWP 5 #define MAX_NUM_CORESET 12 #define MAX_NUM_CCE 90 -#define MAX_HARQ_ROUNDS 4 /*!\brief Maximum number of random access process */ #define NR_NB_RA_PROC_MAX 4 #define MAX_NUM_OF_SSB 64 @@ -91,6 +92,37 @@ typedef struct { int len; } NR_list_t; +typedef struct NR_UE_DL_BWP { + NR_BWP_Id_t bwp_id; + int n_dl_bwp; + int scs; + long *cyclicprefix; + uint16_t BWPSize; + uint16_t BWPStart; + NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList; + NR_PDSCH_Config_t *pdsch_Config; + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig; + uint8_t mcsTableIdx; + nr_dci_format_t dci_format; +} NR_UE_DL_BWP_t; + +typedef struct NR_UE_UL_BWP { + NR_BWP_Id_t bwp_id; + int n_ul_bwp; + int scs; + long *cyclicprefix; + uint16_t BWPSize; + uint16_t BWPStart; + NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList; + NR_PUSCH_Config_t *pusch_Config; + NR_PUCCH_Config_t *pucch_Config; + NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon; + NR_CSI_MeasConfig_t *csi_MeasConfig; + NR_SRS_Config_t *srs_Config; + uint8_t transform_precoding; + uint8_t mcs_table; + nr_dci_format_t dci_format; +} NR_UE_UL_BWP_t; typedef enum { RA_IDLE = 0, @@ -124,10 +156,6 @@ typedef struct NR_sched_pdcch { typedef struct { /// Flag to indicate this process is active RA_gNB_state_t state; - /// DL BWP id of RA process - int dl_bwp_id; - /// UL BWP id of RA process - int ul_bwp_id; /// CORESET0 configured flag int coreset0_configured; /// Slot where preamble was received @@ -199,6 +227,9 @@ typedef struct { rnti_t crnti; /// CFRA flag bool cfra; + // BWP for RA + NR_UE_DL_BWP_t DL_BWP; + NR_UE_UL_BWP_t UL_BWP; } NR_RA_t; /*! \brief gNB common channels */ @@ -346,18 +377,11 @@ typedef struct NR_sched_pucch { * 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 dci_format; int time_domain_allocation; uint8_t nrOfLayers; uint8_t num_dmrs_cdm_grps_no_data; - int startSymbolIndex; int nrOfSymbols; - - NR_PUSCH_Config_t *pusch_Config; - uint8_t transform_precoding; - uint8_t mcs_table; - long mapping_type; NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; uint16_t dmrs_config_type; @@ -409,7 +433,6 @@ typedef struct NR_pdsch_semi_static { int startSymbolIndex; int nrOfSymbols; uint8_t nrOfLayers; - uint8_t mcsTableIdx; uint8_t dmrs_ports_id; uint8_t N_PRB_DMRS; uint8_t N_DMRS_SLOT; @@ -440,6 +463,7 @@ typedef struct NR_sched_pdsch { /// only important for retransmissions; otherwise, the TDA in /// NR_pdsch_semi_static_t has precedence int time_domain_allocation; + uint8_t nrOfLayers; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -508,38 +532,6 @@ struct CSI_Report { #define MAX_SR_BITLEN 8 -typedef struct { - uint8_t nb_ssbri_cri; - uint8_t cri_ssbri_bitlen; - uint8_t rsrp_bitlen; - uint8_t diff_rsrp_bitlen; -}L1_RSRP_bitlen_t; - -typedef struct{ - uint8_t ri_restriction; - uint8_t cri_bitlen; - uint8_t ri_bitlen; - uint8_t li_bitlen[8]; - uint8_t pmi_x1_bitlen[8]; - uint8_t pmi_x2_bitlen[8]; - uint8_t cqi_bitlen[8]; -} CSI_Meas_bitlen_t; - -typedef struct nr_csi_report { - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; - long periodicity; - uint16_t offset; - long ** SSB_Index_list; - long ** CSI_Index_list; -// uint8_t nb_of_nzp_csi_report; - uint8_t nb_of_csi_ssb_report; - L1_RSRP_bitlen_t CSI_report_bitlen; - CSI_Meas_bitlen_t csi_meas_bitlen; - int codebook_mode; - int N1; - int N2; -} nr_csi_report_t; - /*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set @@ -566,11 +558,6 @@ typedef struct NR_UE_ul_harq { /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { - /// the currently active BWP in DL - NR_BWP_Downlink_t *active_bwp; - /// the currently active BWP in UL - NR_BWP_Uplink_t *active_ubwp; - /// the next active BWP ID in DL NR_BWP_Id_t next_dl_bwp_id; /// the next active BWP ID in UL @@ -585,8 +572,6 @@ typedef struct { /// corresponding to the sched_pusch/sched_pdsch structures below int cce_index; uint8_t aggregation_level; - /// maximum aggregation level for UE, can be used to select level - int maxL; /// PUCCH scheduling information. Array of two: HARQ+SR in the first field, /// CSI in second. This order is important for nr_acknack_scheduling()! NR_sched_pucch_t sched_pucch[2]; @@ -673,7 +658,6 @@ typedef struct { } NR_UE_sched_ctrl_t; typedef struct { - boolean_t fiveG_connected; uicc_t *uicc; } NRUEcontext_t; @@ -693,27 +677,34 @@ typedef struct NR_mac_stats { uint32_t pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; + int8_t srs_wide_band_snr; } NR_mac_stats_t; typedef struct NR_bler_options { double upper; double lower; uint8_t max_mcs; + uint8_t harq_round_max; } NR_bler_options_t; +typedef struct nr_mac_rrc_ul_if_s { + /* TODO add other message types as necessary */ + initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; +} nr_mac_rrc_ul_if_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ -#define MAX_CSI_REPORTCONFIG 48 typedef struct { rnti_t rnti; + uid_t uid; // unique ID of this UE /// scheduling control info nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl; + NR_UE_DL_BWP_t current_DL_BWP; + NR_UE_UL_BWP_t current_UL_BWP; NR_mac_stats_t mac_stats; NR_CellGroupConfig_t *CellGroup; char cg_buf[32768]; /* arbitrary size */ asn_enc_rval_t enc_rval; - /// CCE indexing - int m; // UE selected beam index uint8_t UE_beam_index; bool Msg3_dcch_dtch; @@ -731,6 +722,7 @@ typedef struct { pthread_mutex_t mutex; NR_UE_info_t *list[MAX_MOBILES_PER_GNB+1]; bool sched_csirs; + uid_allocator_t uid_allocator; } NR_UEs_t; #define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++))) @@ -759,12 +751,15 @@ typedef struct gNB_MAC_INST_s { int pusch_target_snrx10; /// Pucch target SNR int pucch_target_snrx10; + /// SNR threshold needed to put or not a PRB in the black list + int ul_prbblack_SNR_threshold; /// PUCCH Failure threshold (compared to consecutive PUCCH DTX) int pucch_failure_thres; /// PUSCH Failure threshold (compared to consecutive PUSCH DTX) int pusch_failure_thres; /// Subcarrier Offset int ssb_SubcarrierOffset; + int ssb_OffsetPointA; /// SIB1 Time domain allocation int sib1_tda; int minRXTXTIMEpdsch; @@ -773,7 +768,7 @@ typedef struct gNB_MAC_INST_s { /// current PDU index (BCH,DLSCH) uint16_t pdu_index[NFAPI_CC_MAX]; int num_ulprbbl; - uint16_t ulprbbl[275]; + uint16_t ulprbbl[MAX_BWP_SIZE]; /// NFAPI Config Request Structure nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; /// NFAPI DL Config Request Structure @@ -850,9 +845,10 @@ typedef struct gNB_MAC_INST_s { bool first_MIB; NR_bler_options_t dl_bler; NR_bler_options_t ul_bler; - uint8_t harq_round_max; uint8_t min_grant_prb; uint8_t min_grant_mcs; + + nr_mac_rrc_ul_if_t mac_rrc; } gNB_MAC_INST; #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 108a5dbe91..9adc6ecb5d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -139,7 +139,7 @@ extern volatile int oai_exit; pthread_t pdcp_stats_thread_desc; // will be called when 4G F1 implementation will use GTP-U instead of protobuf -boolean_t cu_f1u_data_req( +bool cu_f1u_data_req( protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, @@ -228,7 +228,7 @@ rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt, __func__, rb_id, size); extern instance_t CUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p); - return TRUE; + return true; } //----------------------------------------------------------------------------- @@ -239,18 +239,16 @@ rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt, * this mem_block_t to be dissected for testing purposes. For further details see test * code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req() */ -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id -) +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) //----------------------------------------------------------------------------- { pdcp_t *pdcp_p = NULL; @@ -261,7 +259,7 @@ boolean_t pdcp_data_req( uint16_t current_sn = 0; mem_block_t *pdcp_pdu_p = NULL; rlc_op_status_t rlc_status; - boolean_t ret = TRUE; + bool ret = true; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 : 0; @@ -277,7 +275,7 @@ boolean_t pdcp_data_req( if (sdu_buffer_sizeP == 0) { LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n"); - return FALSE; + return false; } /* @@ -287,12 +285,12 @@ boolean_t pdcp_data_req( sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < NB_RB_MBMS_MAX, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { if (srb_flagP) { - AssertError (rb_idP < 3, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < 3, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); } else { - AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < LTE_maxDRB, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); } } @@ -304,7 +302,7 @@ boolean_t pdcp_data_req( LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); - return FALSE; + return false; } } @@ -371,7 +369,7 @@ boolean_t pdcp_data_req( memset(&pdu_header.mac_i[0],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); memset(&pdcp_pdu_p->data[sdu_buffer_sizeP + pdcp_header_len],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); - if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == false) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); @@ -382,7 +380,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } } else { pdcp_user_plane_data_pdu_header_with_long_sn pdu_header; @@ -390,7 +388,7 @@ boolean_t pdcp_data_req( pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p); current_sn = pdu_header.sn ; - if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == false) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); @@ -401,7 +399,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } } @@ -422,7 +420,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } LOG_D(PDCP, "Sequence number %d is assigned to current PDU\n", current_sn); @@ -481,7 +479,7 @@ boolean_t pdcp_data_req( ctxt_pP->module_id, rb_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } /* @@ -497,16 +495,16 @@ boolean_t pdcp_data_req( if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type); - ret=FALSE; + ret = false; } else { rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id, destinationL2Id); - ret=FALSE; + ret = false; switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: @@ -544,7 +542,7 @@ boolean_t pdcp_data_req( itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); //CU_send_DL_RRC_MESSAGE_TRANSFER(ctxt_pP->module_id, message_p); LOG_I(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); - ret=TRUE; + ret=true; } else { rlc_status = rlc_data_req(ctxt_pP , srb_flagP @@ -561,27 +559,27 @@ boolean_t pdcp_data_req( switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; + ret= false; break; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; + ret= false; break; } // switch case } @@ -596,7 +594,7 @@ boolean_t pdcp_data_req( /* * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK - * so we return TRUE afterwards + * so we return true afterwards */ for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) { @@ -619,7 +617,7 @@ boolean_t pdcp_data_req( //----------------------------------------------------------------------------- -boolean_t +bool pdcp_data_ind( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, @@ -638,7 +636,7 @@ pdcp_data_ind( pdcp_sn_t sequence_number = 0; volatile sdu_size_t payload_offset = 0; rb_id_t rb_id = rb_idP; - boolean_t packet_forwarded = FALSE; + bool packet_forwarded = false; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; @@ -654,7 +652,7 @@ pdcp_data_ind( "[MSG] PDCP UL %s PDU on rb_id %ld\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); if (MBMS_flagP) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, + AssertError (rb_idP < NB_RB_MBMS_MAX, return false, "RB id is too high (%ld/%d) %u rnti %x!\n", rb_idP, NB_RB_MBMS_MAX, @@ -680,12 +678,12 @@ pdcp_data_ind( } } else { rb_id = rb_idP % LTE_maxDRB; - AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u UE %x!\n", + AssertError (rb_id < LTE_maxDRB, return false, "RB id is too high (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); - AssertError (rb_id > 0, return FALSE, "RB id is too low (%ld/%d) %u UE %x!\n", + AssertError (rb_id > 0, return false, "RB id is too low (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, @@ -700,14 +698,14 @@ pdcp_data_ind( key); free_mem_block(sdu_buffer_pP, __func__); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return FALSE; + return false; } } if (sdu_buffer_sizeP == 0) { LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n"); - return FALSE; + return false; } if (ctxt_pP->enb_flag) { @@ -764,13 +762,13 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return FALSE; + return false; } #if 0 /* Removed by Cedric */ - if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) { + if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == true) { LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number); /* if (dc == PDCP_DATA_PDU ) LOG_D(PDCP, "Passing piggybacked SDU to NAS driver...\n"); @@ -788,7 +786,7 @@ pdcp_data_ind( */ LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); - return FALSE; + return false; } #endif @@ -837,7 +835,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } if (sequence_number < pdcp_p->next_pdcp_rx_sn) @@ -864,7 +862,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } /* if (srb_flagP) */ /* @@ -892,7 +890,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) { pdcp_p->rx_hfn++; rx_hfn_for_count = pdcp_p->rx_hfn; @@ -948,7 +946,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } /* TODO: specs say we have to store this PDU in a list and then deliver @@ -1015,7 +1013,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } break; @@ -1039,7 +1037,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } // XXX Decompression would be done at this point @@ -1051,7 +1049,7 @@ pdcp_data_ind( */ if (LINK_ENB_PDCP_TO_GTPV1U) { - if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { + if ((true == ctxt_pP->enb_flag) && (false == srb_flagP)) { LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %ld len %u\n", ctxt_pP->rnti, rb_id + 4, @@ -1069,10 +1067,10 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - packet_forwarded = TRUE; + packet_forwarded = true; } } else { - packet_forwarded = FALSE; + packet_forwarded = false; } #ifdef MBMS_MULTICAST_OUT @@ -1086,13 +1084,13 @@ pdcp_data_ind( // dest_addr.sin_addr.s_addr = ip_header->daddr; // sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); - // //packet_forwarded = TRUE; + // //packet_forwarded = true; } #endif - if (FALSE == packet_forwarded) { + if (false == packet_forwarded) { notifiedFIFO_elt_t * new_sdu_p = newNotifiedFIFO_elt(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), 0, NULL, NULL); if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) { @@ -1185,7 +1183,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } void pdcp_update_stats(const protocol_ctxt_t *const ctxt_pP) { @@ -1297,7 +1295,7 @@ pdcp_run ( NULL, NULL ); - if (result != TRUE) + if (result != true) LOG_E(PDCP, "PDCP data request failed!\n"); // Message buffer has been processed, free it now. @@ -1420,7 +1418,7 @@ pdcp_mbms_run ( // NULL, NULL // ); // -// if (result != TRUE) +// if (result != true) // LOG_E(PDCP, "PDCP data request failed!\n"); // // // Message buffer has been processed, free it now. @@ -1549,10 +1547,7 @@ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP) { } //----------------------------------------------------------------------------- -boolean_t -pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP -) +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP) //----------------------------------------------------------------------------- { LTE_DRB_Identity_t srb_id = 0; @@ -1599,19 +1594,17 @@ pdcp_remove_UE( //----------------------------------------------------------------------------- -boolean_t -rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list_pP, - LTE_DRB_ToAddModList_t *const drb2add_list_pP, - LTE_DRB_ToReleaseList_t *const drb2release_list_pP, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP, - LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP, - rb_id_t *const defaultDRB -) +bool +rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list_pP, + LTE_DRB_ToAddModList_t *const drb2add_list_pP, + LTE_DRB_ToReleaseList_t *const drb2release_list_pP, + const uint8_t security_modeP, + uint8_t *const kRRCenc_pP, + uint8_t *const kRRCint_pP, + uint8_t *const kUPenc_pP, + LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP, + rb_id_t *const defaultDRB) //----------------------------------------------------------------------------- { long int lc_id = 0; @@ -1669,7 +1662,7 @@ rrc_pdcp_config_asn1_req ( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); free(pdcp_p); - return TRUE; + return true; } else { LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -1784,13 +1777,13 @@ rrc_pdcp_config_asn1_req ( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key_defaultDRB); free(pdcp_p); - return TRUE; + return true; } else if (h_rc != HASH_TABLE_OK) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64" FAILED\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); free(pdcp_p); - return TRUE; + return true; } else { LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -1944,7 +1937,7 @@ rrc_pdcp_config_asn1_req ( if (ctxt_pP->enb_flag) { drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id ;//+ (LTE_maxDRB + 3)*MAX_MOBILES_PER_ENB; // 1 - if (pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { + if (pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == true) { action = CONFIG_ACTION_MBMS_MODIFY; } else { action = CONFIG_ACTION_MBMS_ADD; @@ -1952,7 +1945,7 @@ rrc_pdcp_config_asn1_req ( } else { drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id; // + (LTE_maxDRB + 3); // 15 - if (pdcp_mbms_array_ue[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { + if (pdcp_mbms_array_ue[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == true) { action = CONFIG_ACTION_MBMS_MODIFY; } else { action = CONFIG_ACTION_MBMS_ADD; @@ -1990,23 +1983,22 @@ rrc_pdcp_config_asn1_req ( } //----------------------------------------------------------------------------- -boolean_t -pdcp_config_req_asn1 ( - const protocol_ctxt_t *const ctxt_pP, - pdcp_t *const pdcp_pP, - const srb_flag_t srb_flagP, - const rlc_mode_t rlc_modeP, - const config_action_t actionP, - const uint16_t lc_idP, - const uint16_t mch_idP, - const rb_id_t rb_idP, - const uint8_t rb_snP, - const uint8_t rb_reportP, - const uint16_t header_compression_profileP, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP) +bool +pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const srb_flag_t srb_flagP, + const rlc_mode_t rlc_modeP, + const config_action_t actionP, + const uint16_t lc_idP, + const uint16_t mch_idP, + const rb_id_t rb_idP, + const uint8_t rb_snP, + const uint8_t rb_reportP, + const uint16_t header_compression_profileP, + const uint8_t security_modeP, + uint8_t *const kRRCenc_pP, + uint8_t *const kRRCint_pP, + uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { @@ -2015,7 +2007,7 @@ pdcp_config_req_asn1 ( DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_pP->is_ue = FALSE; + pdcp_pP->is_ue = false; pdcp_add_UE(ctxt_pP); //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; @@ -2035,11 +2027,11 @@ pdcp_config_req_asn1 ( //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } else { - pdcp_pP->is_ue = TRUE; + pdcp_pP->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } - pdcp_pP->is_srb = (srb_flagP == SRB_FLAG_YES) ? TRUE : FALSE; + pdcp_pP->is_srb = srb_flagP == SRB_FLAG_YES; pdcp_pP->lcid = lc_idP; pdcp_pP->rb_id = rb_idP; pdcp_pP->header_compression_profile = header_compression_profileP; @@ -2162,10 +2154,10 @@ pdcp_config_req_asn1 ( rb_idP); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = true ; pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; } else { - pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = true ; pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; } @@ -2245,10 +2237,10 @@ void rrc_pdcp_config_req ( pdcp_p->rb_id = rb_idP; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_p->is_ue = TRUE; + pdcp_p->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { - pdcp_p->is_ue = FALSE; + pdcp_p->is_ue = false; } pdcp_p->next_pdcp_tx_sn = 0; @@ -2321,10 +2313,10 @@ void rrc_pdcp_config_req ( pdcp_p->rb_id = rb_idP; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_p->is_ue = TRUE; + pdcp_p->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { - pdcp_p->is_ue = FALSE; + pdcp_p->is_ue = false; } pdcp_p->next_pdcp_tx_sn = 0; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 332ee382d7..8cbc49d756 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -51,7 +51,7 @@ typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *cons const rb_id_t, const mui_t, confirm_t, sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); -typedef boolean_t (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t, +typedef bool (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t, const MBMS_flag_t, const rb_id_t, const sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); typedef pdcp_data_ind_t* pdcp_data_ind_func_t; @@ -153,14 +153,13 @@ typedef struct pdcp_stats_s { typedef struct pdcp_s { - //boolean_t instanciated_instance; uint16_t header_compression_profile; /* SR: added this flag to distinguish UE/eNB instance as pdcp_run for virtual * mode can receive data on NETLINK for eNB while eNB_flag = 0 and for UE when eNB_flag = 1 */ - boolean_t is_ue; - boolean_t is_srb; + bool is_ue; + bool is_srb; /* Configured security algorithms */ uint8_t cipheringAlgorithm; @@ -217,7 +216,7 @@ typedef struct pdcp_s { } pdcp_t; typedef struct pdcp_mbms_s { - boolean_t instanciated_instance; + bool instanciated_instance; rb_id_t rb_id; } pdcp_mbms_t; @@ -230,7 +229,7 @@ typedef struct pdcp_mbms_s { * under targets/TEST/PDCP/ */ -/*! \fn boolean_t pdcp_data_req(const protocol_ctxt_t* const , srb_flag_t , rb_id_t , mui_t , confirm_t ,sdu_size_t , unsigned char* , pdcp_transmission_mode_t ) +/*! \fn bool pdcp_data_req(const protocol_ctxt_t* const , srb_flag_t , rb_id_t , mui_t , confirm_t ,sdu_size_t , unsigned char* , pdcp_transmission_mode_t ) * \brief This functions handles data transfer requests coming either from RRC or from IP * \param[in] ctxt_pP Running context. * \param[in] rab_id Radio Bearer ID @@ -239,38 +238,34 @@ typedef struct pdcp_mbms_s { * \param[in] sdu_buffer_size Size of incoming SDU in bytes * \param[in] sdu_buffer Buffer carrying SDU * \param[in] mode flag to indicate whether the userplane data belong to the control plane or data plane or transparent -* \return TRUE on success, FALSE otherwise +* \return true on success, false otherwise * \note None * @ingroup _pdcp */ -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode, - const uint32_t * sourceL2Id, - const uint32_t * destinationL2Id -); +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t * sourceL2Id, + const uint32_t * destinationL2Id); -boolean_t cu_f1u_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id - ); +bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id); -/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) +/*! \fn bool pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, bool) * \brief This functions handles data transfer indications coming from RLC * \param[in] ctxt_pP Running context. * \param[in] Shows if rb is SRB @@ -279,7 +274,7 @@ boolean_t cu_f1u_data_req( * \param[in] sdu_buffer_size Size of incoming SDU in bytes * \param[in] sdu_buffer Buffer carrying SDU * \param[in] is_data_plane flag to indicate whether the userplane data belong to the control plane or data plane -* \return TRUE on success, FALSE otherwise +* \return TRUE on success, false otherwise * \note None * @ingroup _pdcp */ @@ -316,20 +311,18 @@ void rrc_pdcp_config_req ( * \param[in] defaultDRB Default DRB ID * \return A status about the processing, OK or error code. */ -boolean_t rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list, - LTE_DRB_ToAddModList_t *const drb2add_list, - LTE_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, - rb_id_t *const defaultDRB -); +bool rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB); -/*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode) +/*! \fn bool pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode) * \brief Function for RRC to configure a Radio Bearer. * \param[in] ctxt_pP Running context. * \param[in] pdcp_pP Pointer on PDCP structure. @@ -349,22 +342,21 @@ boolean_t rrc_pdcp_config_asn1_req ( * \param[in] kUPenc User-Plane encryption key * \return A status about the processing, OK or error code. */ -boolean_t pdcp_config_req_asn1 ( - const protocol_ctxt_t *const ctxt_pP, - pdcp_t *const pdcp_pP, - const srb_flag_t srb_flagP, - const rlc_mode_t rlc_mode, - const uint32_t action, - const uint16_t lc_id, - const uint16_t mch_id, - const rb_id_t rb_id, - const uint8_t rb_sn, - const uint8_t rb_report, - const uint16_t header_compression_profile, - const uint8_t security_mode, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc); +bool pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const srb_flag_t srb_flagP, + const rlc_mode_t rlc_mode, + const uint32_t action, + const uint16_t lc_id, + const uint16_t mch_id, + const rb_id_t rb_id, + const uint8_t rb_sn, + const uint8_t rb_report, + const uint16_t header_compression_profile, + const uint8_t security_mode, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc); /*! \fn void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP) * \brief Function (for RRC) to add a new UE in PDCP module @@ -373,13 +365,12 @@ boolean_t pdcp_config_req_asn1 ( */ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP); -/*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) +/*! \fn bool pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) * \brief Function for RRC to remove UE from PDCP module hashtable * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ -boolean_t pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP); +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP); /*! \fn void rrc_pdcp_config_release( const protocol_ctxt_t* const, rb_id_t) * \brief This functions is unused diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c index ef674132c4..77d3cf3857 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c @@ -32,7 +32,7 @@ #include "pdcp.h" #include "pdcp_primitives.h" -extern boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); +extern bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); /* * Parses data/control field out of buffer of User Plane PDCP Data PDU with @@ -123,13 +123,13 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer) * Fills the incoming buffer with the fields of the header for srb sn * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_control_plane_data_pdu_header* pdu) +bool pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, + pdcp_control_plane_data_pdu_header* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -138,20 +138,20 @@ boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char uint8_t sequence_number = pdu->sn; pdu_buffer[0] = sequence_number & 0x1F; // 5bit sn - return TRUE; + return true; } /* * Fills the incoming buffer with the fields of the header for long sn * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_user_plane_data_pdu_header_with_long_sn* pdu) +bool pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, + pdcp_user_plane_data_pdu_header_with_long_sn* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -170,7 +170,7 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer[0] |= 0x80; // set the first bit as 1 } - return TRUE; + return true; } /* @@ -178,13 +178,14 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* * * @param pdu_buffer The buffer that PDU will be serialized into * @param pdu A status report header - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \ - uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu) +bool pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, + uint8_t bitmap[512], + pdcp_control_pdu_for_pdcp_status_report* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -205,6 +206,6 @@ boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_b */ memcpy(pdu_buffer + 2, bitmap, 512); - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h index 8b5ebe7287..423f69afc9 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h @@ -142,18 +142,18 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer); * Fills the incoming buffer with the fields of the header for SRB1 * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_control_plane_data_pdu_header* pdu); +bool pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, + pdcp_control_plane_data_pdu_header* pdu); /* * Fills the incoming buffer with the fields of the header for long SN (RLC UM and AM) * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_user_plane_data_pdu_header_with_long_sn* pdu); +bool pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, + pdcp_user_plane_data_pdu_header_with_long_sn* pdu); /* * Fills the incoming status report header with given value of bitmap @@ -162,10 +162,11 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* * @param FMS First Missing PDCP SN * @param bitmap Received/Missing sequence number bitmap * @param pdu A status report header - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \ - uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu); +bool pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, + uint8_t bitmap[512], + pdcp_control_pdu_for_pdcp_status_report* pdu); int pdcp_netlink_dequeue_element(const protocol_ctxt_t* const ctxt_pP, struct pdcp_netlink_element_s **data_ppP); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c index cdc583ef21..31beb3a9e0 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c @@ -33,12 +33,12 @@ /* * Initializes sequence numbering state * @param pdcp_entity The PDCP entity to be initialized - * @return boolean_t TRUE on success, FALSE otherwise + * @return bool true on success, false otherwise */ -boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity) +bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity) { if (pdcp_entity == NULL) { - return FALSE; + return false; } /* Sequence number state variables */ @@ -55,34 +55,34 @@ boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity) // Shall UE and eNB behave differently on initialization? (see 7.1.e) pdcp_entity->last_submitted_pdcp_rx_sn = 4095; - return TRUE; + return true; } -boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity) +bool pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity) { if (pdcp_entity == NULL) { - return FALSE; + return false; } // Check if the size of SN is valid (see 3GPP TS 36.323 v10.1.0 item 6.3.2) if (pdcp_entity->seq_num_size != 5 && pdcp_entity->seq_num_size != 7 && pdcp_entity->seq_num_size != 12) { LOG_W(PDCP, "Incoming SN size is invalid! (Expected: {5 | 7 | 12}, Received: %d\n", pdcp_entity->seq_num_size); - return FALSE; + return false; } - return TRUE; + return true; } /** * Check if SN number is in the range according to SN size */ -boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size) +bool pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size) { if (seq_num >= 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size)) { - return TRUE; + return true; } - return FALSE; + return false; } uint16_t pdcp_calculate_max_seq_num_for_given_size(uint8_t seq_num_size) @@ -96,7 +96,7 @@ uint16_t pdcp_calculate_max_seq_num_for_given_size(uint8_t seq_num_size) uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity) { - if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) { + if (pdcp_is_seq_num_size_valid(pdcp_entity) == false) { return -1; } @@ -118,10 +118,10 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity) return pdcp_seq_num; } -boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity) +bool pdcp_advance_rx_window(pdcp_t* pdcp_entity) { - if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) { - return FALSE; + if (pdcp_is_seq_num_size_valid(pdcp_entity) == false) { + return false; } /* @@ -137,10 +137,10 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity) pdcp_entity->next_pdcp_rx_sn++; } - return TRUE; + return true; } -boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity) +bool pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity) { /* * Incoming sequence number and PDCP entity were already @@ -158,5 +158,5 @@ boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entit LOG_D(PDCP, "Marking %d. bit of %d. octet of status bitmap\n", (seq_num % 8) + 1, octet_index); util_mark_nth_bit_of_octet(&pdcp_entity->missing_pdu_bitmap[octet_index], seq_num % 8); util_print_binary_representation((uint8_t*)"Current state of relevant octet: ", pdcp_entity->missing_pdu_bitmap[octet_index]); - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h index 172c9810e6..bff98d1b00 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h @@ -35,17 +35,17 @@ * @param pdcp_entity The PDCP entity to be initialized * @return none */ -boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity); +bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity); /** * Checks if incoming PDCP entitiy pointer and relevant sequence number size is valid - * @return TRUE (0x01) if it is valid, FALSE (0x00) otherwise + * @return true (0x01) if it is valid, false (0x00) otherwise */ -boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity); +bool pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity); /** * Check if SN number is in the range according to SN size - * @return TRUE if it is valid, FALSE otherwise + * @return true if it is valid, false otherwise */ -boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size); +bool pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size); /** * Returns the maximum allowed sequence number value for given size of SN field * @return Max sequence number value @@ -58,11 +58,11 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity); /** * Advances the RX window state of given PDCP entity upon successfull receipt of a SDU */ -boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity); +bool pdcp_advance_rx_window(pdcp_t* pdcp_entity); /** * Updates missing PDU bitmap with incoming sequence number -* @return TRUE if successful, FALSE otherwise +* @return true if successful, false otherwise */ -boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity); +bool pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity); #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c index cf8218829f..79f6d68820 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c @@ -130,9 +130,9 @@ void util_print_binary_representation(unsigned char* message, uint8_t octet) * * @param octet 8-bit data * @param index Index of bit to be set - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) +bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) { uint8_t mask = 0x80; @@ -148,6 +148,6 @@ boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) */ *octet |= mask; - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h index 49846c7a9f..89b8ff672f 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h @@ -66,8 +66,8 @@ void util_print_binary_representation(unsigned char* message, uint8_t octet); * * @param octet Octet * @param index Index - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); +bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); #endif // PDCP_UTIL_H diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 4eb0907046..ddc7bf85e8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -52,7 +52,7 @@ rlc_am_get_status_pdu_buffer_occupancy( rlc_sn_t sn_cursor = rlc_pP->vr_r; rlc_sn_t sn_prev = rlc_pP->vr_r; rlc_sn_t sn_end = rlc_pP->vr_ms; - boolean_t segment_loop_end = false; + bool segment_loop_end = false; if (sn_prev != sn_end) { while ((RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r)) && (cursor_p != NULL)) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 1b6d837565..95c47943a4 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -54,7 +54,7 @@ typedef struct rlc_am_entity_s { rb_id_t rb_id; /*!< \brief Radio bearer identifier, for statistics and trace purpose. */ logical_chan_id_t channel_id; /*!< \brief Transport channel identifier. */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ rlc_buffer_occupancy_t sdu_buffer_occupancy; /*!< \brief Number of bytes of unsegmented SDUs. */ rlc_buffer_occupancy_t status_buffer_occupancy; /*!< \brief Number of bytes of control PDUs waiting for transmission. */ @@ -76,7 +76,7 @@ typedef struct rlc_am_entity_s { rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer; /*!< \brief Transmission PDU data buffer. Used also for retransmissions */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. Only payload is taken into account */ - boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ + bool force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ //--------------------------------------------------------------------- // RX BUFFERS @@ -186,8 +186,8 @@ typedef struct rlc_am_entity_s { // note occupancy of other buffers is deducted from nb elements in lists rlc_buffer_occupancy_t buffer_occupancy_retransmission_buffer; /*!< \brief Number of PDUs. */ - boolean_t initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ - boolean_t configured; /*!< \brief Boolean for rlc_am_entity_t struct configuration. */ + bool initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ + bool configured; /*!< \brief Boolean for rlc_am_entity_t struct configuration. */ } rlc_am_entity_t; /** @} */ # endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index cb09f24855..8ff29fa44b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -32,7 +32,7 @@ rlc_am_init( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP) { - if (rlc_pP->initialized == TRUE) { + if (rlc_pP->initialized == true) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); } else { @@ -79,7 +79,7 @@ rlc_am_init( rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } } //----------------------------------------------------------------------------- @@ -134,7 +134,7 @@ rlc_am_reestablish( rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } @@ -197,7 +197,7 @@ rlc_am_configure( const uint32_t t_reorderingP, const uint32_t t_status_prohibitP) { - if (rlc_pP->configured == TRUE) { + if (rlc_pP->configured == true) { LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), max_retx_thresholdP, @@ -235,7 +235,7 @@ rlc_am_configure( rlc_am_init_timer_reordering (ctxt_pP, rlc_pP, t_reorderingP); rlc_am_init_timer_status_prohibit(ctxt_pP, rlc_pP, t_status_prohibitP); - rlc_pP->configured = TRUE; + rlc_pP->configured = true; } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 0957c20bdf..a5f0b4f9ef 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -183,12 +183,10 @@ rlc_am_send_sdu ( } } //----------------------------------------------------------------------------- -void -rlc_am_reassemble_pdu( - const protocol_ctxt_t *const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - mem_block_t *const tb_pP, - boolean_t free_rlc_pdu) { +void rlc_am_reassemble_pdu(const protocol_ctxt_t *const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + mem_block_t *const tb_pP, + bool free_rlc_pdu) { int i,j; rlc_am_pdu_info_t *pdu_info = &((rlc_am_rx_pdu_management_t *)(tb_pP->data))->pdu_info; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU SN=%03d\n", diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h index bf9bd58fb5..839e7d9304 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h @@ -57,14 +57,14 @@ void rlc_am_reassembly (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * */ void rlc_am_send_sdu (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP); -/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP,boolean_t free_rlc_pdu) +/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP, bool free_rlc_pdu) * \brief Reassembly a RLC AM PDU, depending of the content of this PDU, data will be reassemblied to the current output SDU, the current will be sent to higher layers or not, after or before the reassembly, or no send of SDU will be triggered, depending on FI field in PDU header. * \param[in] ctxtP Running context. * \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] tb_pP RLC AM PDU embedded in a mem_block_t. * \param[in] free_rlc_pdu Flag for freeing RLC AM PDU after reassembly. */ -void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP,boolean_t free_rlc_pdu); +void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP, bool free_rlc_pdu); /** @} */ #endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index 916d1513b0..a749aa035e 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -328,7 +328,7 @@ rlc_am_receive_process_data_pdu ( rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP; rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; - boolean_t reassemble = false; + bool reassemble = false; if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 56b37e1e39..7129307739 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -29,13 +29,12 @@ #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" //----------------------------------------------------------------------------- -boolean_t rlc_am_nack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - const rlc_sn_t snP, - const rlc_sn_t prev_nack_snP, - sdu_size_t so_startP, - sdu_size_t so_endP) +bool rlc_am_nack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + const rlc_sn_t snP, + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP) { // 5.2.1 Retransmission // ... @@ -54,8 +53,8 @@ boolean_t rlc_am_nack_pdu ( rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; //int pdu_sdu_index; //int sdu_index; - boolean_t status = TRUE; - boolean_t retx_count_increment = FALSE; + bool status = true; + bool retx_count_increment = false; sdu_size_t pdu_data_to_retx = 0; if (mb_p != NULL) { @@ -63,7 +62,7 @@ boolean_t rlc_am_nack_pdu ( if(so_startP > so_endP) { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, so_startP %d, so_endP %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_startP, so_endP); - status = FALSE; + status = false; } // Handle full PDU NACK first else if ((so_startP == 0) && (so_endP == 0x7FFF)) { @@ -71,9 +70,7 @@ boolean_t rlc_am_nack_pdu ( pdu_data_to_retx = tx_data_pdu_buffer_p->payload_size; /* Increment VtReTxNext if this is the first NACK or if some segments have already been transmitted */ if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (tx_data_pdu_buffer_p->nack_so_start)) - { - retx_count_increment = TRUE; - } + retx_count_increment = true; tx_data_pdu_buffer_p->nack_so_start = 0; tx_data_pdu_buffer_p->num_holes = 0; @@ -89,11 +86,11 @@ boolean_t rlc_am_nack_pdu ( if(tx_data_pdu_buffer_p->nack_so_start >= tx_data_pdu_buffer_p->payload_size){ LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, nack_so_start %d, payload_size %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),tx_data_pdu_buffer_p->nack_so_start, tx_data_pdu_buffer_p->payload_size); - status = FALSE; + status = false; } } else { - status = FALSE; + status = false; } } else if (tx_data_pdu_buffer_p->flags.max_retransmit == 0) { @@ -107,9 +104,8 @@ boolean_t rlc_am_nack_pdu ( if (prev_nack_snP != snP) { /* New NACK_SN with SO */ /* check whether a new segment is to be placed in Retransmission Buffer, then increment vrReTx */ - if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (so_startP < tx_data_pdu_buffer_p->nack_so_start)) { - retx_count_increment = TRUE; - } + if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (so_startP < tx_data_pdu_buffer_p->nack_so_start)) + retx_count_increment = true; tx_data_pdu_buffer_p->num_holes = 1; tx_data_pdu_buffer_p->retx_hole_index = 0; @@ -129,21 +125,18 @@ boolean_t rlc_am_nack_pdu ( tx_data_pdu_buffer_p->nack_so_stop = so_endP; tx_data_pdu_buffer_p->num_holes ++; pdu_data_to_retx = so_endP - so_startP + 1; + } else { + status = false; } - else { - status = FALSE; - } - } - else { - status = FALSE; + } else { + status = false; } } else { - status = FALSE; + status = false; } - } - else { - status = FALSE; + } else { + status = false; } if (status) { @@ -175,17 +168,16 @@ boolean_t rlc_am_nack_pdu ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU SN %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP); - status = FALSE; + status = false; } return status; } //----------------------------------------------------------------------------- -void rlc_am_ack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - const rlc_sn_t snP, - boolean_t free_pdu) +void rlc_am_ack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + const rlc_sn_t snP, + bool free_pdu) { mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block; rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; @@ -283,7 +275,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdu_size_t retx_so_start,retx_so_stop; //starting and ending SO for retransmission in this PDU rlc_sn_t sn = pdu_mngt->sn; uint16_t header_so_part; - boolean_t fi_start, fi_end; + bool fi_start, fi_end; uint8_t sdu_index = 0; uint8_t sdu_segment_index = 0; uint8_t num_LIs_pdu_segment = pdu_mngt->nb_sdus - 1; @@ -377,11 +369,11 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Set FI part to false if SO Start and SO End are different from PDU boundaries */ if (retx_so_start) { - fi_start = FALSE; + fi_start = false; } if (retx_so_stop < pdu_mngt->payload_size - 1) { - fi_end = FALSE; + fi_end = false; } /* Header content is filled at the end */ @@ -423,7 +415,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( else { /* if retx_so_start is still not included then set data_size with full original PDU data size */ - /* Set fi_start to FALSE in this case */ + /* Set fi_start to false in this case */ data_size = pdu_mngt->payload_size; } sdu_index ++; @@ -432,7 +424,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( if (retx_so_start == data_size) { /* Set FI Start if retx_so_start = cumulated data size */ - fi_start = TRUE; + fi_start = true; /* there must be at least one SDU more */ //Assertion(eNB)_PRAN_DesignDocument_annex No.778 if(sdu_index >= pdu_mngt->nb_sdus) @@ -464,8 +456,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( } else if (retx_so_start != 0) { - /* in all other cases set fi_start to FALSE if it SO Start is not 0 */ - fi_start = FALSE; + /* in all other cases set fi_start to false if it SO Start is not 0 */ + fi_start = false; } /* Set first SDU portion of the segment */ @@ -582,10 +574,10 @@ mem_block_t* rlc_am_retransmit_get_am_segment( "RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d numLIPDU=%d sn=%d LcId=%d !\n", retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id); */ - /* init FI End to FALSE if retx_so_stop is not end of PDU */ + /* init FI End to false if retx_so_stop is not end of PDU */ if (retx_so_stop != pdu_mngt->payload_size - 1) { - fi_end = FALSE; + fi_end = false; } /* Check consistency between sdus_segment_size and payload_sizeP */ @@ -596,7 +588,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( data_size += sdus_segment_size[i]; if ((retx_so_stop == data_size - 1) && (i < num_LIs_pdu_segment)) { - fi_end = TRUE; + fi_end = true; } } //Assertion(eNB)_PRAN_DesignDocument_annex No.782 @@ -665,7 +657,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( pdu_mngt->nack_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; } - /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* Content is supposed to be init with 0 so with FIStart=FIEnd=true */ RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); RLC_AM_PDU_SET_RF(*pdu_segment_header_p); /* Change FI */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h index fc52689314..c34d06337d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h @@ -35,7 +35,7 @@ # ifndef __RLC_AM_RETRANSMIT_H__ # define __RLC_AM_RETRANSMIT_H__ //----------------------------------------------------------------------------- -/*! \fn boolean_t rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, int16_t snP, int16_t prev_nack_snP,sdu_size_t so_startP, sdu_size_t so_endP) +/*! \fn bool rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, int16_t snP, int16_t prev_nack_snP,sdu_size_t so_startP, sdu_size_t so_endP) * \brief The RLC AM PDU which have the sequence number snP is marked NACKed with segment offset fields. * \param[in] ctxtP Running context. * \param[in] rlcP RLC AM protocol instance pointer. @@ -46,13 +46,12 @@ * \return OK/KO * \note It may appear a new hole in the retransmission buffer depending on the segment offset informations. Depending on the state of the retransmission buffer, negative confirmation can be sent to higher layers about the drop by the RLC AM instance of a particular SDU. */ -boolean_t rlc_am_nack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlcP, - const rlc_sn_t snP, - const rlc_sn_t prev_nack_snP, - sdu_size_t so_startP, - sdu_size_t so_endP); +bool rlc_am_nack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlcP, + const rlc_sn_t snP, + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP); /*! \fn void rlc_am_ack_pdu (const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t *rlcP, rlc_sn_t snP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. @@ -62,11 +61,10 @@ boolean_t rlc_am_nack_pdu ( * \param[in] free_pdu Boolean indicating that the PDU can be freed because smaller than new vtA. * \note Depending on the state of the retransmission buffer, positive confirmation can be sent to higher layers about the receiving by the peer RLC AM instance of a particular SDU. */ -void rlc_am_ack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlcP, - const rlc_sn_t snP, - boolean_t free_pdu); +void rlc_am_ack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlcP, + const rlc_sn_t snP, + bool free_pdu); /*! \fn mem_block_t* rlc_am_retransmit_get_copy (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, rlc_sn_t snP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 4a06553901..bd578abab2 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -31,14 +31,13 @@ #include "common/utils/LOG/log.h" -boolean_t rlc_am_rx_check_vr_reassemble( - const protocol_ctxt_t* const ctxt_pP, - const rlc_am_entity_t* const rlc_pP) +bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP, + const rlc_am_entity_t* const rlc_pP) { mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = NULL; sdu_size_t next_waited_so = 0; - boolean_t reassemble = FALSE; + bool reassemble = false; if (cursor_p != NULL) { @@ -48,7 +47,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( if (sn_ref != rlc_pP->vr_r) { /* Case vrR has advanced from head : most likely case */ - reassemble = TRUE; + reassemble = true; /* Handle first SN if it is made of PDU segments : set them all to be reassembled */ if (pdu_info_p->rf) { pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); @@ -58,7 +57,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n", sn_ref,rlc_pP->vr_r,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received > 0,"AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n", @@ -94,7 +93,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n", rlc_pP->vr_r,sn_ref,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n", @@ -123,7 +122,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n", rlc_pP->vr_r,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n", @@ -132,7 +131,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) { if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; - reassemble = TRUE; + reassemble = true; } next_waited_so += pdu_info_p->payload_size; cursor_p = cursor_p->next; @@ -157,7 +156,7 @@ mem_block_t * create_new_segment_from_pdu( int16_t new_li_list[RLC_AM_MAX_SDU_IN_PDU]; int16_t header_size = 0; uint8_t num_li = 0; - boolean_t fi_start, fi_end, lsf; + bool fi_start, fi_end, lsf; /* Init some PDU Segment header fixed parameters */ fi_start = !((pdu_rx_info_p->fi & 0x2) >> 1); @@ -170,11 +169,11 @@ mem_block_t * create_new_segment_from_pdu( header_size = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; if (so_offset) { - fi_start = FALSE; + fi_start = false; } if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { - fi_end = FALSE; - lsf = FALSE; + fi_end = false; + lsf = false; } } // end no LI in original segment else { @@ -185,7 +184,7 @@ mem_block_t * create_new_segment_from_pdu( /* set LSF to false if we know that end of the original segment will not be copied */ if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { - lsf = FALSE; + lsf = false; } /* catch the first LI containing so_offset */ @@ -223,7 +222,7 @@ mem_block_t * create_new_segment_from_pdu( num_li = j; /* set FI End if remaining size = 0 */ if (remaining_size == 0) { - fi_end = TRUE; + fi_end = true; } } } @@ -263,7 +262,7 @@ mem_block_t * create_new_segment_from_pdu( } /* Fill Header part in the buffer */ - /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* Content is supposed to be init with 0 so with FIStart=FIEnd=true */ /* copy first two bytes from original: D/C + RF + FI + E+ SN*/ memset(pdu_segment_header_p, 0, header_size); RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); @@ -1106,7 +1105,7 @@ rlc_am_rx_list_reassemble_rlc_sdus( do { if (rlc_am_rx_pdu_management_p->all_segments_received > 0) { cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); - rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,TRUE); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p, true); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; cursor_p = list2_get_head(&rlc_pP->receiver_buffer); @@ -1123,7 +1122,7 @@ rlc_am_rx_list_reassemble_rlc_sdus( else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) { rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED; - rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p, false); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; cursor_p = cursor_p->next; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h index fd8704964d..18e423312c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h @@ -61,13 +61,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_check_duplicate_insert_pdu(const protocol_ */ signed int rlc_am_rx_list_insert_pdu(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP); -/*! \fn boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP) +/*! \fn bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP) * \brief Check if reassembly taking into account potential new vrR value * \param[in] ctxt_pP Running context. * \param[in] rlcP RLC AM protocol instance pointer. -* \return TRUE if reassembly must be done, FALSE else +* \return true if reassembly must be done, false else */ -boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP); +bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP); /*! \fn void rlc_am_rx_check_all_byte_segments(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP) * \brief Check if all sub-segments of a PDU are received, if yes then call rlc_am_rx_mark_all_segments_received() procedure. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index ed81e119ac..9e7c3338f8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -32,12 +32,11 @@ #include "common/utils/LOG/log.h" //----------------------------------------------------------------------------- -void rlc_am_pdu_polling ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - rlc_am_pdu_sn_10_t *const pdu_pP, - const int16_t payload_sizeP, - boolean_t is_new_pdu) +void rlc_am_pdu_polling(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + rlc_am_pdu_sn_10_t *const pdu_pP, + const int16_t payload_sizeP, + bool is_new_pdu) { // 5.2.2 Polling // An AM RLC entity can poll its peer AM RLC entity in order to trigger STATUS reporting at the peer AM RLC entity. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h index dc754d08e4..1e472302c8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h @@ -36,14 +36,14 @@ # define __RLC_AM_SEGMENT_H__ //----------------------------------------------------------------------------- -/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu) +/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP, bool is_new_pdu) * \brief Set or not the poll bit in the PDU header depending on RLC AM protocol variables. * \param[in] ctxt_pP Running context. * \param[in] rlcP RLC AM protocol instance pointer. * \param[in] pduP Pointer on the header of the PDU in order to be able to set the poll bit if necessary. * \param[in] payload_sizeP Size of the payload of the PDU. */ -void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu); +void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP, bool is_new_pdu); /*! \fn void rlc_am_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlcP) * \brief Segment a PDU with 10 bits sequence number, based on segmentation information given by MAC (size to transmit). diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 02a0247a03..f1e6c961e7 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -237,7 +237,7 @@ rlc_am_receive_process_control_pdu( rlc_sn_t nack_sn,prev_nack_sn; sdu_size_t data_cnf_so_stop = 0x7FFF; unsigned int nack_index; - boolean_t status = TRUE; + bool status = true; if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, tb_size_in_bytes_pP, &rlc_pP->control_pdu_info) >= 0) { rlc_am_tx_buffer_display(ctxt_pP, rlc_pP, " TX BUFFER BEFORE PROCESS OF STATUS PDU"); @@ -282,7 +282,7 @@ rlc_am_receive_process_control_pdu( if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a)) { if (rlc_pP->control_pdu_info.num_nack == 0) { while (sn_cursor != ack_sn) { - rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE); + rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, true); sn_cursor = RLC_AM_NEXT_SN(sn_cursor); } @@ -294,7 +294,7 @@ rlc_am_receive_process_control_pdu( prev_nack_sn = 0x3FFF; while (sn_cursor != nack_sn) { - rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE); + rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, true); sn_cursor = RLC_AM_NEXT_SN(sn_cursor); } @@ -316,7 +316,7 @@ rlc_am_receive_process_control_pdu( rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, - FALSE); + false); } else { status = rlc_am_nack_pdu (ctxt_pP, rlc_pP, @@ -348,13 +348,13 @@ rlc_am_receive_process_control_pdu( LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,rlc_pP->vt_a,rlc_pP->vt_s); *tb_size_in_bytes_pP = 0; - status = FALSE; + status = false; } } else { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); *tb_size_in_bytes_pP = 0; - status = FALSE; + status = false; } if (status) { @@ -480,8 +480,8 @@ rlc_am_send_status_pdu( int waited_so = 0; mem_block_t *tb_p = NULL; sdu_size_t pdu_size = 0; - boolean_t status_report_completed = false; - boolean_t segment_loop_end = false; + bool status_report_completed = false; + bool segment_loop_end = false; memset(&control_pdu_info, 0, sizeof(rlc_am_control_pdu_info_t)); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] nb_bits_to_transmit %d (15 already allocated for header)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c index 7a95a62787..e898a601c2 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c @@ -1170,7 +1170,7 @@ void rlc_am_v9_3_0_test(void) { // initscr(); // cbreak(); - // keypad(stdscr, TRUE); + // keypad(stdscr, true); // under test pool_buffer_init(); set_comp_log(RLC, LOG_ERR, LOG_MED, 1); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index 969ed2d7a5..7aead2f30a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -111,7 +111,7 @@ rlc_am_check_timer_poll_retransmit( } - rlc_pP->force_poll= TRUE; + rlc_pP->force_poll = true; //BugFix : new ms_time_out is computed when next poll is transmitter } } diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c index 4e3fffe176..f079696aa9 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c @@ -31,13 +31,11 @@ #include "list.h" #include "LAYER2/MAC/mac_extern.h" //----------------------------------------------------------------------------- -void -rlc_tm_send_sdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlc_pP, - const boolean_t error_indicationP, - uint8_t * const srcP, - const sdu_size_t length_in_bitsP) +void rlc_tm_send_sdu(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlc_pP, + const bool error_indicationP, + uint8_t * const srcP, + const sdu_size_t length_in_bitsP) { int length_in_bytes; #if DEBUG_RLC_TM_DISPLAY_ASCII_DATA diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h index d2bab33b1a..de7b9b8170 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h @@ -51,7 +51,7 @@ /*! \fn void rlc_tm_send_sdu ( * const protocol_ctxt_t* const ctxt_pP, * rlc_tm_entity_t * const rlc_pP, -* const boolean_t error_indicationP, +* const bool error_indicationP, * uint8_t * const srcP, * const sdu_size_t length_in_bitsP) * \brief Send SDU if any reassemblied to upper layer. @@ -60,12 +60,11 @@ * \param[in] srcP SDU data pointer. * \param[in] length_in_bitsP Length of SDU in bits. */ -void rlc_tm_send_sdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlc_pP, - const boolean_t error_indicationP, - uint8_t * const srcP, - const sdu_size_t length_in_bitsP); +void rlc_tm_send_sdu(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlc_pP, + const bool error_indicationP, + uint8_t * const srcP, + const sdu_size_t length_in_bitsP); /*! \fn void rlc_tm_no_segment (const protocol_ctxt_t* const ctxt_pP, rlc_tm_entity_t * const rlcP) * \brief Schedule a SDU to be transmited by lower layers. diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h index 1a13982df6..3c2f1804be 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h @@ -40,14 +40,13 @@ * \brief Structure containing a RLC TM instance protocol variables, allocation variables, buffers and other miscellaneous variables. */ typedef struct rlc_tm_entity { - boolean_t allocation; /*!< \brief Boolean for rlc_tm_entity_t struct allocation. */ + bool allocation; /*!< \brief Boolean for rlc_tm_entity_t struct allocation. */ rlc_protocol_state_t protocol_state; /*!< \brief Protocol state, can be RLC_NULL_STATE, RLC_DATA_TRANSFER_READY_STATE, RLC_LOCAL_SUSPEND_STATE. */ - boolean_t is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ // for stats and trace purpose : logical_chan_id_t channel_id; /*!< \brief Transport channel identifier. */ rb_id_t rb_id; /*!< \brief Radio bearer identifier, for statistics and trace purpose. */ - //boolean_t is_enb; /*!< \brief To know if the RLC belongs to a eNB or UE. */ //----------------------------- // tranmission //----------------------------- diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c index 22e6f4d78d..a838b2a006 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c @@ -133,10 +133,9 @@ rlc_tm_cleanup ( } //----------------------------------------------------------------------------- -void rlc_tm_configure( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP, - const boolean_t is_uplink_downlinkP) +void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP, + const bool is_uplink_downlinkP) { rlcP->is_uplink_downlink = is_uplink_downlinkP; rlc_tm_reset_state_variables (ctxt_pP, rlcP); diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h index 57e2116a72..f315a0311a 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h @@ -78,27 +78,24 @@ void rlc_tm_init ( * \brief Reset protocol variables and state variables to initial values. * \param[in] rlcP RLC TM protocol instance pointer. */ -void rlc_tm_reset_state_variables ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP); +void rlc_tm_reset_state_variables(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP); /*! \fn void rlc_tm_cleanup(rlc_tm_entity_t * const rlcP) * \brief Free all allocated memory (lists and buffers) previously allocated by this RLC TM instance. * \param[in] rlcP RLC TM protocol instance pointer. */ -void rlc_tm_cleanup( - rlc_tm_entity_t * const rlcP); +void rlc_tm_cleanup(rlc_tm_entity_t * const rlcP); -/*! \fn void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP,rlc_tm_entity_t * const rlcP, const boolean_t is_uplink_downlinkP) +/*! \fn void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP,rlc_tm_entity_t * const rlcP, const bool is_uplink_downlinkP) * \brief Configure RLC TM protocol parameters. * \param[in] rlcP RLC TM protocol instance pointer. * \param[in] is_uplink_downlinkP Is this instance is TRANSMITTER_ONLY, RECEIVER_ONLY, or TRANSMITTER_AND_RECEIVER. */ -void rlc_tm_configure( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP, - const boolean_t is_uplink_downlinkP); +void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP, + const bool is_uplink_downlinkP); /*! \fn void rlc_tm_set_debug_infos(const protocol_ctxt_t* const ctxt_pP, rlc_tm_entity_t * const rlcP, const rb_id_t rb_idP, const srb_flag_t srb_flagP) * \brief Set debug informations for a RLC TM protocol instance, these informations are only for trace purpose. diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index bec815ac5d..f2cb4f09b1 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -263,7 +263,7 @@ rlc_um_init ( } rlc_pP->first_pdu = 1; - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } } //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h index 3250ac85b8..7bfa3d60ff 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h @@ -53,12 +53,11 @@ typedef struct rlc_um_timer_s { */ typedef struct rlc_um_entity_s { - boolean_t initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ - boolean_t is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ + bool initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ + bool is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ rlc_protocol_state_t protocol_state; /*!< \brief Protocol state, can be RLC_NULL_STATE, RLC_DATA_TRANSFER_READY_STATE, RLC_LOCAL_SUSPEND_STATE. */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ - //boolean_t is_enb; /*!< \brief To know if the RLC belongs to a eNB or UE. */ - boolean_t is_mxch; /*!< \brief To know if the RLC belongs to a MBMS bearer. */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_mxch; /*!< \brief To know if the RLC belongs to a MBMS bearer. */ //----------------------------- // PROTOCOL VARIABLES //----------------------------- @@ -114,7 +113,7 @@ typedef struct rlc_um_entity_s { //----------------------------- // STATISTICS //----------------------------- - boolean_t first_pdu; /*!< \brief Act as a boolean, tells if the next PDU is the first PDU to be received. */ + bool first_pdu; /*!< \brief Act as a boolean, tells if the next PDU is the first PDU to be received. */ unsigned int stat_tx_pdcp_sdu; /*!< \brief Number of SDUs received from upper layers. */ unsigned int stat_tx_pdcp_bytes; /*!< \brief Number of SDU bytes received from upper layers. */ diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index b9dcf0414b..ec90817500 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -41,13 +41,12 @@ #include "common/ran_context.h" extern RAN_CONTEXT_t RC; -extern boolean_t pdcp_data_ind( - const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_idP, - const sdu_size_t sdu_buffer_sizeP, - mem_block_t *const sdu_buffer_pP); +extern bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, + mem_block_t *const sdu_buffer_pP); #define DEBUG_RLC_PDCP_INTERFACE 1 //#define TRACE_RLC_PAYLOAD 1 @@ -397,7 +396,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN); - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { log_ch_id = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][log_ch_id]; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 1e5b7947d7..1e17ff96bf 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -107,7 +107,7 @@ typedef struct { rlc_buffer_occupancy_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ frame_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ sdu_size_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ - boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ + bool head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ } mac_rlc_status_resp_t; diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index 89cbe4c406..0e1cb89fd7 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -425,8 +425,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( /* Assumptions : for UE only */ /* At each TTI, Buffer Occupancy is first computed in mac_rlc_status_ind called by MAC ue_scheduler() function */ /* Then this function is called during MAC multiplexing ue_get_sdu(), and it may be call several times for the same bearer if it is in AM mode and there are several PDU types to transmit */ - //AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP); - if(enb_flagP != FALSE) { + //AssertFatal(enb_flagP == false,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP); + if(enb_flagP != false) { LOG_E(RLC, "Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%u\n", channel_idP); return 0; } diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 4313f379fe..ed9af5efb2 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -480,7 +480,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( /* for no gcc warnings */ (void)lcid; - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; @@ -581,7 +581,7 @@ rlc_union_t *rrc_rlc_add_rlc ( rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; - if (MBMS_flagP == FALSE) { + if (MBMS_flagP == false) { //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); if(rb_idP >= NB_RB_MAX) { @@ -595,7 +595,7 @@ rlc_union_t *rrc_rlc_add_rlc ( } } - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; @@ -640,11 +640,11 @@ rlc_union_t *rrc_rlc_add_rlc ( } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { rlc_union_p = calloc(1, sizeof(rlc_union_t)); h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p); - if(MBMS_flagP != TRUE) + if(MBMS_flagP != true) h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", PROTOCOL_CTXT_ARGS(ctxt_pP), mbms_id_p->service_id, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 7e1ddb62bd..480b651593 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -27,6 +27,7 @@ #include "nr_pdcp_security_nea2.h" #include "nr_pdcp_integrity_nia2.h" +#include "nr_pdcp_integrity_nia1.h" #include "nr_pdcp_sdu.h" #include "LOG/log.h" @@ -240,16 +241,21 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, } if (integrity_algorithm != 0 && integrity_algorithm != -1) { - if (integrity_algorithm != 2) { - LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n"); - exit(1); - } entity->has_integrity = 1; if (entity->free_integrity != NULL) entity->free_integrity(entity->integrity_context); - entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); - entity->integrity = nr_pdcp_integrity_nia2_integrity; - entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; + if (integrity_algorithm == 2) { + entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); + entity->integrity = nr_pdcp_integrity_nia2_integrity; + entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; + } else if (integrity_algorithm == 1) { + entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key); + entity->integrity = nr_pdcp_integrity_nia1_integrity; + entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity; + } else { + LOG_E(PDCP, "FATAL: only nia1 and nia2 supported for the moment\n"); + exit(1); + } } if (ciphering_algorithm == 0) { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c new file mode 100644 index 0000000000..08ec959937 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c @@ -0,0 +1,66 @@ +/* + * 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 + */ + +#include "nr_pdcp_integrity_nia1.h" + +#include +#include +#include +#include + +#include "UTIL/OSA/osa_defs.h" + +int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]); + +void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key) +{ + stream_cipher_t *ret; + + ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort(); + ret->key = malloc(16); if (ret->key == NULL) abort(); + memcpy(ret->key, integrity_key, 16); + ret->key_length = 16; /* unused */ + + return ret; +} + +void nr_pdcp_integrity_nia1_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + stream_cipher_t *ctx = integrity_context; + + ctx->message = buffer; + ctx->count = count; + ctx->bearer = bearer-1; + ctx->direction = direction; + ctx->blength = length * 8; + + stream_compute_integrity_eia1(ctx, out); +} + +void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context) +{ + stream_cipher_t *ctx = integrity_context; + free(ctx->key); + free(ctx); +} diff --git a/openair2/COMMON/itti_sim_messages_types.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h similarity index 53% rename from openair2/COMMON/itti_sim_messages_types.h rename to openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h index 2e29e8f508..5c44bad4a7 100644 --- a/openair2/COMMON/itti_sim_messages_types.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h @@ -19,33 +19,16 @@ * contact@openairinterface.org */ -/*! \file itti_sim_messages_types.h - * \brief itti message for itti simulator - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ +#ifndef _NR_PDCP_INTEGRITY_NIA1_H_ +#define _NR_PDCP_INTEGRITY_NIA1_H_ -#ifndef ITTI_SIM_MESSAGES_TYPES_H_ -#define ITTI_SIM_MESSAGES_TYPES_H_ +void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key); -#include "LTE_asn_constant.h" +void nr_pdcp_integrity_nia1_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction); +void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context); - -#define GNB_RRC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBBCCHind -#define GNB_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBCCCHind -#define GNB_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBDCCHind -#define UE_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UECCCHind -#define UE_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UEDCCHind - - - -typedef struct itti_sim_rrc_ch_s { - rb_id_t rbid; - uint8_t *sdu; - int size; -} itti_sim_rrc_ch_t; - -#endif /* ITTI_SIM_MESSAGES_TYPES_H_ */ +#endif /* _NR_PDCP_INTEGRITY_NIA1_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ea4b7e80c7..47c630e0c9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -274,9 +274,8 @@ static void do_pdcp_data_ind( if (rb != NULL) { rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size); } else { - LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n", + LOG_E(PDCP, "%s:%d:%s: no RB found (rb_id %ld, srb_flag %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP); - exit(1); } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); @@ -360,15 +359,14 @@ static void enqueue_pdcp_data_ind( if (pthread_mutex_unlock(&pq.m) != 0) abort(); } -boolean_t pdcp_data_ind( - const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_id, - const sdu_size_t sdu_buffer_size, - mem_block_t *const sdu_buffer, - const uint32_t *const srcID, - const uint32_t *const dstID) +bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_id, + const sdu_size_t sdu_buffer_size, + mem_block_t *const sdu_buffer, + const uint32_t *const srcID, + const uint32_t *const dstID) { enqueue_pdcp_data_ind(ctxt_pP, srb_flagP, @@ -439,7 +437,7 @@ static void *enb_tun_read_thread(void *_) ctxt.rnti = rnti; uint8_t qfi = 7; - boolean_t rqi = 0; + bool rqi = 0; int pdusession_id = 10; sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, @@ -485,13 +483,13 @@ static void *ue_tun_read_thread(void *_) ctxt.rnti = rnti; - boolean_t dc = SDAP_HDR_UL_DATA_PDU; - uint8_t qfi = 7; - int pdusession_id = 10; + bool dc = SDAP_HDR_UL_DATA_PDU; + extern uint8_t nas_qfi; + extern uint8_t nas_pduid; sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, - PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, dc, pdusession_id); + PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, nas_qfi, dc, nas_pduid); } return NULL; @@ -593,8 +591,10 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; netlink_init_tun(ifsuffix_ue, num_if, id); //Add --nr-ip-over-lte option check for next line - if (IS_SOFTMODEM_NOS1) - nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); + if (IS_SOFTMODEM_NOS1){ + nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); + set_qfi_pduid(7, 10); + } LOG_I(PDCP, "UE pdcp will use tun interface\n"); start_pdcp_tun_ue(); } else if(ENB_NAS_USE_TUN) { @@ -736,27 +736,30 @@ static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity, __FILE__, __LINE__, __FUNCTION__, ue->rnti); exit(1); - srb_found: - { - uint8_t *rrc_buffer_p = entity->is_gnb ? - itti_malloc(TASK_PDCP_ENB, TASK_RRC_GNB, size): - itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size); - MessageDef *message_p; - - AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY"); - memcpy(rrc_buffer_p, buf, size); - message_p = entity->is_gnb ? - itti_alloc_new_message(TASK_PDCP_ENB, 0, NR_RRC_DCCH_DATA_IND): - itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND); - - AssertFatal(message_p != NULL, "OUT OF MEMORY"); - NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; - NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; - NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; - NR_RRC_DCCH_DATA_IND(message_p).rnti = ue->rnti; - - itti_send_msg_to_task(entity->is_gnb ? TASK_RRC_GNB : TASK_RRC_NRUE, 0, message_p); - } +srb_found: + if (entity->is_gnb) { + MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE); + AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); + f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p); + ul_rrc->rnti = ue->rnti; + ul_rrc->srb_id = srb_id; + ul_rrc->rrc_container = malloc(size); + AssertFatal(ul_rrc->rrc_container != NULL, "OUT OF MEMORY\n"); + memcpy(ul_rrc->rrc_container, buf, size); + ul_rrc->rrc_container_length = size; + itti_send_msg_to_task(TASK_RRC_GNB, 0, message_p); + } else { + uint8_t *rrc_buffer_p = itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size); + AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY\n"); + memcpy(rrc_buffer_p, buf, size); + MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND); + AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); + NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; + NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; + NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; + NR_RRC_DCCH_DATA_IND(message_p).rnti = ue->rnti; + itti_send_msg_to_task(TASK_RRC_NRUE, 0, message_p); + } } static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity, @@ -859,7 +862,7 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP) RRC_DCCH_DATA_REQ(msg_p).mode, NULL, NULL); - if (result != TRUE) + if (result != true) LOG_E(PDCP, "PDCP data request failed!\n"); result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p); AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); @@ -951,7 +954,7 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, int has_sdap = 0; int has_sdapULheader=0; int has_sdapDLheader=0; - boolean_t is_sdap_DefaultDRB = false; + bool is_sdap_DefaultDRB = false; NR_QFI_t *mappedQFIs2Add = NULL; uint8_t mappedQFIs2AddCount=0; if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) @@ -1034,20 +1037,18 @@ static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, LOG_I(PDCP, "%s:%s:%d: added DRB for UE RNTI %x\n", __FILE__, __FUNCTION__, __LINE__, rnti); } -boolean_t nr_rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - NR_SRB_ToAddModList_t *const srb2add_list, - NR_DRB_ToAddModList_t *const drb2add_list, - NR_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - uint8_t *const kUPint - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) - //struct NR_RLC_Config *rlc_Config) +bool nr_rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + uint8_t *const kUPint, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) { int rnti = ctxt_pP->rnti; int i; @@ -1105,17 +1106,16 @@ boolean_t nr_rrc_pdcp_config_asn1_req( } /* Dummy function due to dependency from LTE libraries */ -boolean_t rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list, - LTE_DRB_ToAddModList_t *const drb2add_list, - LTE_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB) +bool rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB) { return 0; } @@ -1220,8 +1220,7 @@ uint64_t get_pdcp_optmask(void) return pdcp_optmask; } -boolean_t pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP) +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP) { int rnti = ctxt_pP->rnti; @@ -1276,13 +1275,12 @@ void pdcp_config_set_security( nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static boolean_t pdcp_data_req_srb( - protocol_ctxt_t *ctxt_pP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer) +static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer) { LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size); nr_pdcp_ue_t *ue; @@ -1323,13 +1321,12 @@ static boolean_t pdcp_data_req_srb( } -static boolean_t pdcp_data_req_drb( - protocol_ctxt_t *ctxt_pP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer) +static bool pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer) { LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size); nr_pdcp_ue_t *ue; @@ -1369,19 +1366,16 @@ static boolean_t pdcp_data_req_drb( return 1; } -boolean_t cu_f1u_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode - ,const uint32_t *const sourceL2Id - ,const uint32_t *const destinationL2Id - ) { - +bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) { //Force instance id to 0, OAI incoherent instance management ctxt_pP->instance=0; mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__); @@ -1398,18 +1392,16 @@ boolean_t cu_f1u_data_req( return ret; } -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode - ,const uint32_t *const sourceL2Id - ,const uint32_t *const destinationL2Id - ) +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) { if (srb_flagP) { return pdcp_data_req_srb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index fefe2fc77d..1883bbdd6c 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -77,14 +77,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_am_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; - ret->common.set_time = nr_rlc_entity_am_set_time; - ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_am_reestablishment; - ret->common.delete = nr_rlc_entity_am_delete; + ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_am_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; + ret->common.set_time = nr_rlc_entity_am_set_time; + ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_am_reestablishment; + ret->common.delete = nr_rlc_entity_am_delete; + ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -127,14 +128,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_um_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; - ret->common.set_time = nr_rlc_entity_um_set_time; - ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_um_reestablishment; - ret->common.delete = nr_rlc_entity_um_delete; + ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_um_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; + ret->common.set_time = nr_rlc_entity_um_set_time; + ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_um_reestablishment; + ret->common.delete = nr_rlc_entity_um_delete; + ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -158,14 +160,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ret->tx_maxsize = tx_maxsize; - ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; - ret->common.set_time = nr_rlc_entity_tm_set_time; - ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; - ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; + ret->common.set_time = nr_rlc_entity_tm_set_time; + ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; + ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index b9b638fe07..5cd3bee650 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -50,6 +50,8 @@ typedef struct nr_rlc_entity_t { void (*delete)(struct nr_rlc_entity_t *entity); + int (*available_tx_space)(struct nr_rlc_entity_t *entity); + /* callbacks provided to the RLC module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 2382db267f..91e2bed11a 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -1910,3 +1910,9 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h index 57ae1a3485..4c626c4826 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -99,5 +99,6 @@ void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c index 75408276d1..f85edbba0f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -174,3 +174,9 @@ void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h index 7c8c7e40a0..7918703799 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -51,5 +51,6 @@ void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index b34a7dc894..5f2fd592a0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -695,3 +695,9 @@ void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h index 21063a1ea1..c40e72ada1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -75,5 +75,6 @@ void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 7ba08aaa71..4bd4ea75fd 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -101,6 +101,7 @@ void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config switch (rlc_config_pr){ case NR_RLC_Config_PR_um_Bi_Directional: // RLC UM Bi-directional Bearer configuration + LOG_I(RLC, "RLC UM Bi-directional Bearer configuration selected \n"); rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional)); rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; @@ -213,10 +214,12 @@ tbs_size_t mac_rlc_data_req( } if (rb != NULL) { + LOG_D(RLC, "MAC PDU to get created for channel_idP:%d \n", channel_idP); rb->set_time(rb, nr_rlc_current_time); maxsize = tb_sizeP; ret = rb->generate_pdu(rb, buffer_pP, maxsize); } else { + LOG_D(RLC, "MAC PDU failed to get created for channel_idP:%d \n", channel_idP); ret = 0; } @@ -394,6 +397,35 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP) +{ + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + int ret; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; + case 4 ... 8: rb = ue->drb[channel_idP - 4]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + ret = rb->available_tx_space(rb); + } else { + LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + ret = -1; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 6b3c228163..92fbba9bec 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -46,4 +46,8 @@ void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerCo void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr); -void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); \ No newline at end of file +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); + +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP); diff --git a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz index 45e54651eb..53cea67c98 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz index ddb895d56f..61fa016634 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test8.txt.gz b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz index c20d43c63b..461ae1aeba 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test8.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test9.txt.gz b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz index 27590b7d71..938fcd6ddc 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test9.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index 2a6f00c13c..11ae770e3e 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -1065,3 +1065,15 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, sdu_sizeP, sdu_pP, NULL, NULL); } + +/* HACK to be removed: nr_rlc_get_available_tx_space is needed by + * openair3/ocp-gtpu/gtp_itf.cpp which is compiled in lte-softmodem + * so let's put a dummy nr_rlc_get_available_tx_space here + */ +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP) +{ + abort(); + return 0; +} diff --git a/openair2/M2AP/m2ap_common.c b/openair2/M2AP/m2ap_common.c index d288a0a114..aa090d124d 100644 --- a/openair2/M2AP/m2ap_common.c +++ b/openair2/M2AP/m2ap_common.c @@ -31,27 +31,6 @@ #include "m2ap_common.h" #include "M2AP_M2AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t m2ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair2/M2AP/m2ap_common.h b/openair2/M2AP/m2ap_common.h index 95da064b4a..2e84c51938 100644 --- a/openair2/M2AP/m2ap_common.h +++ b/openair2/M2AP/m2ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef M2AP_COMMON_H_ +#define M2AP_COMMON_H_ #include "M2AP_ProtocolIE-Field.h" #include "M2AP_M2AP-PDU.h" @@ -38,9 +36,6 @@ #include "common/ran_context.h" -#ifndef M2AP_COMMON_H_ -#define M2AP_COMMON_H_ - /** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ @@ -55,11 +50,6 @@ # define M2AP_PORT 36423 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index f63408259c..d86e32e561 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -198,7 +198,8 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -267,7 +268,8 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -285,7 +287,8 @@ static const struct net_device_ops nasmesh_netdev_ops = { .ndo_set_mac_address = NULL, .ndo_set_config = nas_set_config, .ndo_do_ioctl = nas_CTL_ioctl, -#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1797 && LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797 && RHEL_RELEASE_CODE != 2403) .extended.ndo_change_mtu = nas_change_mtu, #else .ndo_change_mtu = nas_change_mtu, diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 0ff9a73925..bf858a0005 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -239,7 +239,8 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) { // End debug information netif_stop_queue(dev_pP); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -315,7 +316,8 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -333,7 +335,7 @@ static const struct net_device_ops ue_ip_netdev_ops = { .ndo_set_mac_address = ue_ip_set_mac_address, .ndo_set_config = ue_ip_set_config, .ndo_do_ioctl = NULL, -#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797) +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797 && RHEL_RELEASE_CODE != 2403 .extended.ndo_change_mtu = ue_ip_change_mtu, #else .ndo_change_mtu = ue_ip_change_mtu, diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index ac0e48a910..47705082d1 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -215,6 +215,41 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) UL_info->crc_ind.number_crcs = 0; } +void handle_nr_srs(NR_UL_IND_t *UL_info) { + + if(NFAPI_MODE == NFAPI_MODE_PNF) { + if (UL_info->srs_ind.number_of_pdus > 0) { + LOG_D(PHY,"PNF Sending UL_info->srs_ind.number_of_pdus: %d, SFN/SF:%d.%d \n", + UL_info->srs_ind.number_of_pdus, UL_info->frame, UL_info->slot); + oai_nfapi_nr_srs_indication(&UL_info->srs_ind); + UL_info->srs_ind.number_of_pdus = 0; + } + return; + } + + const module_id_t module_id = UL_info->module_id; + const frame_t frame = UL_info->srs_ind.sfn; + const sub_frame_t slot = UL_info->srs_ind.slot; + const int num_srs = UL_info->srs_ind.number_of_pdus; + const nfapi_nr_srs_indication_pdu_t *srs_list = UL_info->srs_ind.pdu_list; + + for (int i = 0; i < num_srs; i++) { + const nfapi_nr_srs_indication_pdu_t *srs_ind = &srs_list[i]; + LOG_D(NR_PHY, "(%d.%d) UL_info->srs_ind.pdu_list[%d].rnti: 0x%04x\n", frame, slot, i, srs_ind->rnti); + handle_nr_srs_measurements(module_id, + frame, + slot, + srs_ind->rnti, + srs_ind->timing_advance, + srs_ind->num_symbols, + srs_ind->wide_band_snr, + srs_ind->num_reported_symbols, + srs_ind->reported_symbol_list); + } + + UL_info->srs_ind.number_of_pdus = 0; +} + static void free_unqueued_nfapi_indications(nfapi_nr_rach_indication_t *rach_ind, nfapi_nr_uci_indication_t *uci_ind, nfapi_nr_rx_data_indication_t *rx_ind, @@ -431,6 +466,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { // clear UL DCI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; handle_nr_ulsch(UL_info); + handle_nr_srs(UL_info); if (get_softmodem_params()->emulate_l1) { free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index b8b79f8399..cefafcba80 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -66,17 +66,6 @@ queue_t nr_tx_req_queue; queue_t nr_ul_dci_req_queue; queue_t nr_ul_tti_req_queue; -static slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; - -//static int get_mcs_from_sinr(float sinr); -//static int get_cqi_from_mcs(void); -static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index); -//static bool did_drop_transport_block(int slot, uint16_t rnti); -static float get_bler_val(uint8_t mcs, int sinr); -static bool should_drop_transport_block(int slot, uint16_t rnti); -static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request); -static inline bool is_channel_modeling(void); - void nrue_init_standalone_socket(int tx_port, int rx_port) { { @@ -939,7 +928,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea return; } -static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request) +void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request) { int count_sent = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(0); @@ -1114,6 +1103,10 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u return 0; } +int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) { + return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements); +} + void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -1239,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; - free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu); + free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu); break; case FAPI_NR_RX_PDU_TYPE_SIB: ret_mask |= (handle_bcch_dlsch(dl_info->module_id, @@ -1254,6 +1247,12 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ case FAPI_NR_RX_PDU_TYPE_RAR: ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR; break; + case FAPI_NR_CSIRS_IND: + ret_mask |= (handle_csirs_measurements(dl_info->module_id, + dl_info->frame, + dl_info->slot, + &(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND; + break; default: break; } @@ -1343,245 +1342,3 @@ void RCconfig_nr_ue_L1(void) { } } } - -/* -static int get_mcs_from_sinr(float sinr) -{ - if (sinr < (nr_bler_data[0].bler_table[0][0])) - { - LOG_D(NR_MAC, "The SINR found is smaller than first MCS table\n"); - return 0; - } - - if (sinr > (nr_bler_data[NR_NUM_MCS-1].bler_table[nr_bler_data[NR_NUM_MCS-1].length - 1][0])) - { - LOG_D(NR_MAC, "The SINR found is larger than last MCS table\n"); - return NR_NUM_MCS-1; - } - - for (int n = NR_NUM_MCS-1; n >= 0; n--) - { - CHECK_INDEX(nr_bler_data, n); - float largest_sinr = (nr_bler_data[n].bler_table[nr_bler_data[n].length - 1][0]); - float smallest_sinr = (nr_bler_data[n].bler_table[0][0]); - if (sinr < largest_sinr && sinr > smallest_sinr) - { - LOG_D(NR_MAC, "The SINR found in MCS %d table\n", n); - return n; - } - } - LOG_E(NR_MAC, "Unable to get an MCS value.\n"); - abort(); -} -*/ - -/* -static int get_cqi_from_mcs(void) -{ - static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15}; - assert(NUM_ELEMENTS(mcs_to_cqi) == NR_NUM_MCS); - int slot = 0; - while (slot < NUM_NFAPI_SLOT) - { - if (slot_rnti_mcs[slot].latest) - { - int num_pdus = slot_rnti_mcs[slot].num_pdus; - if (num_pdus <= 0) - { - LOG_E(NR_MAC, "%s: slot_rnti_mcs[%d].num_pdus = 0\n", __FUNCTION__, slot); - abort(); - } - - CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); - int mcs = get_mcs_from_sinr(slot_rnti_mcs[slot].sinr); - CHECK_INDEX(mcs_to_cqi, mcs); - int cqi = mcs_to_cqi[mcs]; - LOG_D(NR_MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", slot_rnti_mcs[slot].sinr, mcs, cqi); - return cqi; - } - slot++; - } - LOG_E(NR_MAC, "Unable to get CQI value because no MCS found\n"); - abort(); -} -*/ - -static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) -{ - if (pdu == NULL) - { - LOG_E(NR_MAC,"PDU NULL\n"); - abort(); - } - - /* This function is executed for every pdsch pdu type in a dl_tti_request. We save - the assocaited MCS and RNTI value for each. The 'index' passed in is a count of - how many times we have called this function for a particular dl_tti_request. It - allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/ - for (int i = 0; i < NUM_NFAPI_SLOT; i++) - { - slot_rnti_mcs[i].latest = false; - } - - CHECK_INDEX(slot_rnti_mcs[slot].rnti, index); - CHECK_INDEX(slot_rnti_mcs[slot].mcs, index); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index); - slot_rnti_mcs[slot].rnti[index] = pdu->rnti; - slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0]; - slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0]; - slot_rnti_mcs[slot].drop_flag[index] = false; - slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus - slot_rnti_mcs[slot].latest = true; - LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot); - - return; -} - -/* -static bool did_drop_transport_block(int slot, uint16_t rnti) -{ - int num_pdus = slot_rnti_mcs[slot].num_pdus; - if (num_pdus <= 0) - { - LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n"); - return true; - } - CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); - for (int n = 0; n < num_pdus; n++) - { - if (slot_rnti_mcs[slot].rnti[n] == rnti && slot_rnti_mcs[slot].drop_flag[n]) - { - return true; - } - } - return false; -} -*/ - -static float get_bler_val(uint8_t mcs, int sinr) -{ - // 4th col = dropped packets, 5th col = total packets - float bler_val = 0.0; - CHECK_INDEX(nr_bler_data, mcs); - LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr, - (int)(nr_bler_data[mcs].bler_table[0][0] * 10), - (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10) - ); - - if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10)) - { - LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs); - bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5]; - return bler_val; - } - if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)) - { - LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs); - bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5]; - return bler_val; - } - // Loop through bler table to find sinr_index - for (int i = 0; i < nr_bler_data[mcs].length; i++) - { - int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10); - if (temp_sinr == sinr) - { - bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; - return bler_val; - } - // Linear interpolation when SINR is between indices - if (temp_sinr > sinr) - { - float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5]; - float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; - LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2); - return ((bler_val1 + bler_val2) / 2); - } - } - LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n"); - abort(); - -} - -static inline bool is_channel_modeling(void) -{ - /* TODO: For now we enable channel modeling based on the node_number. - Replace with a command line option to enable/disable channel modeling. - The LTE UE will crash when channel modeling is conducted for NSA - mode. It does not crash for LTE mode. We have not implemented channel - modeling for NSA mode yet. For now, we ensure only do do channel modeling - in LTE/NR mode. */ - return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa; -} - -static bool should_drop_transport_block(int slot, uint16_t rnti) -{ - if (!is_channel_modeling()) - { - return false; - } - - /* We want to avoid dropping setup messages because this would be pathological. */ - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - if (mac->ra.ra_state < RA_SUCCEEDED) - { - LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state); - return false; - } - - /* Get block error rate (bler_val) from table based on every saved - MCS and SINR to be used as the cutoff rate for dropping packets. - Generate random uniform vairable to compare against bler_val. */ - int num_pdus = slot_rnti_mcs[slot].num_pdus; - assert(slot < 20 && slot >= 0); - LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n", - rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr); - assert(num_pdus > 0); - CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); - int n = 0; - uint8_t mcs = 99; - for (n = 0; n < num_pdus; n++) - { - if (slot_rnti_mcs[slot].rnti[n] == rnti) - { - mcs = slot_rnti_mcs[slot].mcs[n]; - } - if (mcs != 99) - { - /* Use MCS to get the bler value. Since there can be multiple MCS - values for a particular slot, we verify that all PDUs are not - flagged for drop before returning. If even one is flagged for drop - we return immediately because we drop the entire packet. */ - - LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n", - slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr); - - float bler_val; - if (slot_rnti_mcs[slot].rvIndex[n] != 0) - bler_val = 0; - else - bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10))); - double drop_cutoff = ((double) rand() / (RAND_MAX)); - assert(drop_cutoff <= 1); - LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]); - if (drop_cutoff <= bler_val) - { - slot_rnti_mcs[slot].drop_flag[n] = true; - LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot); - return slot_rnti_mcs[slot].drop_flag[n]; - } - } - - } - - if (mcs == 99) - { - LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n); - abort(); - } - return false; -} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 45d1a071ca..f663c17d10 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -40,45 +40,12 @@ #include "openair2/PHY_INTERFACE/queue_t.h" #include "nfapi_nr_interface_scf.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" +#include "NR_Packet_Drop.h" -#define NR_NUM_MCS 29 -#define NUM_SINR 100 -#define NUM_BLER_COL 13 -#define NUM_NFAPI_SLOT 20 -#define NR_NUM_LAYER 1 +extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t; -typedef struct nr_phy_channel_params_t -{ - uint16_t sfn_slot; - uint16_t message_id; - uint16_t nb_of_sinrs; - float sinr[NR_NUM_LAYER]; - // Incomplete, need all channel parameters -} nr_phy_channel_params_t; - -typedef struct -{ - uint8_t slot; - uint16_t rnti[256]; - uint8_t mcs[256]; - uint8_t rvIndex[256]; - float sinr; - uint16_t num_pdus; - bool drop_flag[256]; - bool latest; - -} slot_rnti_mcs_s; - -typedef struct -{ - uint16_t length; - float bler_table[NUM_SINR][NUM_BLER_COL]; -} nr_bler_struct; - -extern nr_bler_struct nr_bler_data[NR_NUM_MCS]; - typedef enum { ONLY_PUSCH, NOT_PUSCH, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c new file mode 100644 index 0000000000..97938c6b02 --- /dev/null +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -0,0 +1,183 @@ +/* + * 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 + */ +#include +#include "openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h" +#include "executables/softmodem-common.h" +#include "NR_MAC_UE/mac_proto.h" + +slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; +void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) +{ + if (pdu == NULL) + { + LOG_E(NR_MAC,"PDU NULL\n"); + abort(); + } + + /* This function is executed for every pdsch pdu type in a dl_tti_request. We save + the assocaited MCS and RNTI value for each. The 'index' passed in is a count of + how many times we have called this function for a particular dl_tti_request. It + allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/ + for (int i = 0; i < NUM_NFAPI_SLOT; i++) + { + slot_rnti_mcs[i].latest = false; + } + + CHECK_INDEX(slot_rnti_mcs[slot].rnti, index); + CHECK_INDEX(slot_rnti_mcs[slot].mcs, index); + CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index); + slot_rnti_mcs[slot].rnti[index] = pdu->rnti; + slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0]; + slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0]; + slot_rnti_mcs[slot].drop_flag[index] = false; + slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus + slot_rnti_mcs[slot].latest = true; + LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot); + + return; +} + +extern nr_bler_struct nr_bler_data[NR_NUM_MCS]; +float get_bler_val(uint8_t mcs, int sinr) +{ + // 4th col = dropped packets, 5th col = total packets + float bler_val = 0.0; + CHECK_INDEX(nr_bler_data, mcs); + LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr, + (int)(nr_bler_data[mcs].bler_table[0][0] * 10), + (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10) + ); + + if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10)) + { + LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs); + bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5]; + return bler_val; + } + if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)) + { + LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs); + bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5]; + return bler_val; + } + // Loop through bler table to find sinr_index + for (int i = 0; i < nr_bler_data[mcs].length; i++) + { + int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10); + if (temp_sinr == sinr) + { + bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; + return bler_val; + } + // Linear interpolation when SINR is between indices + if (temp_sinr > sinr) + { + float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5]; + float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; + LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2); + return ((bler_val1 + bler_val2) / 2); + } + } + LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n"); + abort(); + +} + +bool is_channel_modeling(void) +{ + /* TODO: For now we enable channel modeling based on the node_number. + Replace with a command line option to enable/disable channel modeling. + The LTE UE will crash when channel modeling is conducted for NSA + mode. It does not crash for LTE mode. We have not implemented channel + modeling for NSA mode yet. For now, we ensure only do do channel modeling + in LTE/NR mode. */ + return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa; +} + +bool should_drop_transport_block(int slot, uint16_t rnti) +{ + if (!is_channel_modeling()) + { + return false; + } + + /* We want to avoid dropping setup messages because this would be pathological. */ + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + if (mac->ra.ra_state < RA_SUCCEEDED) + { + LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state); + return false; + } + + /* Get block error rate (bler_val) from table based on every saved + MCS and SINR to be used as the cutoff rate for dropping packets. + Generate random uniform vairable to compare against bler_val. */ + int num_pdus = slot_rnti_mcs[slot].num_pdus; + assert(slot < 20 && slot >= 0); + LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n", + rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr); + assert(num_pdus > 0); + CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); + CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); + CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); + int n = 0; + uint8_t mcs = 99; + for (n = 0; n < num_pdus; n++) + { + if (slot_rnti_mcs[slot].rnti[n] == rnti) + { + mcs = slot_rnti_mcs[slot].mcs[n]; + } + if (mcs != 99) + { + /* Use MCS to get the bler value. Since there can be multiple MCS + values for a particular slot, we verify that all PDUs are not + flagged for drop before returning. If even one is flagged for drop + we return immediately because we drop the entire packet. */ + + LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n", + slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr); + + float bler_val; + if (slot_rnti_mcs[slot].rvIndex[n] != 0) + bler_val = 0; + else + bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10))); + double drop_cutoff = ((double) rand() / (RAND_MAX)); + assert(drop_cutoff <= 1); + LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]); + if (drop_cutoff <= bler_val) + { + slot_rnti_mcs[slot].drop_flag[n] = true; + LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot); + return slot_rnti_mcs[slot].drop_flag[n]; + } + } + + } + + if (mcs == 99) + { + LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n); + abort(); + } + return false; +} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h new file mode 100644 index 0000000000..549eb5c2e3 --- /dev/null +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h @@ -0,0 +1,68 @@ +/* + * 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 + */ +#ifndef __NR_CHAN_MODEL_H__ +#define __NR_CHAN_MODEL_H__ + +#include +#include +#include +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" + +#define NR_NUM_MCS 29 +#define NUM_SINR 100 +#define NUM_BLER_COL 13 +#define NUM_NFAPI_SLOT 20 +#define NR_NUM_LAYER 1 +#define MAX_CHAN_PARAMS 256 + +typedef struct nr_phy_channel_params_t +{ + uint16_t sfn_slot; + uint16_t message_id; + uint16_t nb_of_sinrs; + float sinr[NR_NUM_LAYER]; +} nr_phy_channel_params_t; + +typedef struct +{ + uint8_t slot; + uint16_t rnti[MAX_CHAN_PARAMS]; + uint8_t mcs[MAX_CHAN_PARAMS]; + uint8_t rvIndex[MAX_CHAN_PARAMS]; + float sinr; + uint16_t num_pdus; + bool drop_flag[MAX_CHAN_PARAMS]; + bool latest; +} slot_rnti_mcs_s; + +typedef struct +{ + uint16_t length; + float bler_table[NUM_SINR][NUM_BLER_COL]; +} nr_bler_struct; + +void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index); +void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request); +float get_bler_val(uint8_t mcs, int sinr); +bool should_drop_transport_block(int slot, uint16_t rnti); +bool is_channel_modeling(void); + +#endif diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index c4650f18f3..cd57ea9ff1 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1956,7 +1956,7 @@ static int get_mcs_from_sinr(float sinr) static int get_cqi_from_mcs(void) { - static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15}; + static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS); int sf = 0; while(sf < NUM_NFAPI_SUBFRAME) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index d68d1dffdd..fe0e7be12e 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -21,7 +21,7 @@ //#include "openair1/PHY/LTE_TRANSPORT/defs.h" #include "queue_t.h" -#define NUM_MCS 28 +#define NUM_MCS 29 #define NUM_SINR 100 #define NUM_BLER_COL 13 #define LTE_NUM_LAYER 1 diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index a4239e857d..f0c4e94c99 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -306,7 +306,7 @@ rrc_rx_tx( LOG_D(RRC,"SFN.SN %d.%d => release timer %d/%d\n",ctxt_pP->frame,ctxt_pP->subframe, ue_context_p->ue_context.ue_release_timer,ue_context_p->ue_context.ue_release_timer_thres); if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/20000\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 0a63acc8fb..c12d2aa873 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -299,7 +299,7 @@ mac_rrc_data_ind( const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP, - const boolean_t brOption + const bool brOption ) //-------------------------------------------------------------------------- { diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index 1993fe7de0..660bd91dda 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -58,7 +58,7 @@ rrc_data_req( { if(sdu_sizeP == 255) { LOG_I(RRC,"sdu_sizeP == 255"); - return FALSE; + return false; } MessageDef *message_p; @@ -94,7 +94,7 @@ rrc_data_req( if (ctxt_pP->enb_flag && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) pdcp_run(ctxt_pP); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } //------------------------------------------------------------------------------ diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 534030864a..850ecf1b58 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -298,7 +298,7 @@ rrc_data_req_ue( TASK_PDCP_UE, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index c34c65b195..e5024e3505 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -343,7 +343,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, if (in_coverage > 0 ) { //in coverage - mib_sl->inCoverage_r12 = TRUE; + mib_sl->inCoverage_r12 = true; mib_sl->sl_Bandwidth_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth; if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { @@ -366,7 +366,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, } else { //Todo - out of coverage for V2X // Todo - UE has a selected SyncRef UE - mib_sl->inCoverage_r12 = FALSE; + mib_sl->inCoverage_r12 = false; //set sl-Bandwidth, subframeAssignmentSL and reserved from the pre-configured parameters } @@ -989,7 +989,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1250->nonCriticalExtension = NULL; ////Rel1310 if ((configuration->schedulingInfoSIB1_BR_r13[CC_id] != 0) && - (brOption==TRUE)) { + (brOption==true)) { sib1_1250->nonCriticalExtension = calloc(1, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); memset(sib1_1250->nonCriticalExtension, 0, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_1310 = sib1_1250->nonCriticalExtension; @@ -1279,7 +1279,7 @@ uint8_t do_SIB23(uint8_t Mod_id, *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; - if ((configuration->eMBMS_configured > 0) && (brOption==FALSE)) { + if ((configuration->eMBMS_configured > 0) && (brOption==false)) { sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; @@ -2781,7 +2781,7 @@ do_RRCConnectionSetup( mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; // max number of UL HARQ transmission mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 // regular BSR timer - mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // false //* timeAlignmentTimerDedicated *// mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; //* DRX Config *// @@ -3135,7 +3135,7 @@ uint8_t do_RRCConnectionSetup_BR( //mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; - mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // false mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; mac_MainConfig->drx_Config = NULL; mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index c76bdea53f..17ef77ff17 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -37,9 +37,6 @@ #include "COMMON/s1ap_messages_types.h" #include "COMMON/rrc_messages_types.h" -#if ITTI_SIM -#include "COMMON/itti_sim_messages_types.h" -#endif #include "collection/tree.h" #include "rrc_types_NB_IoT.h" @@ -156,7 +153,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { #define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 typedef struct UE_S_TMSI_NB_IoT_s { - boolean_t presence; + bool presence; mme_code_t mme_code; m_tmsi_t m_tmsi; } __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 9b37853ed2..577ee3effd 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -4351,8 +4351,8 @@ void rrc_ue_generate_nrMeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t AssertFatal(size >= 0, "do_nrMeasurementReport failed \n"); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); - int result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); - AssertFatal (result == TRUE, "PDCP data request failed!\n"); + const bool result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); + AssertFatal (result == true, "PDCP data request failed!\n"); } } } @@ -4370,7 +4370,6 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e long nElem, nElem1; float rsrp_filtered, rsrq_filtered; static frame_t pframe=0; - int result; nElem = 98; nElem1 = 35; target_eNB_offset = UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB @@ -4420,8 +4419,8 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e AssertFatal(size >= 0, "do_MeasurementReport failed \n"); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d. Size is %zu\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index, size); - result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); - AssertFatal (result == TRUE, "PDCP data request failed!\n"); + const bool result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); + AssertFatal (result == true, "PDCP data request failed!\n"); //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH); } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 64baf5e2ac..f5841b09f8 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -36,11 +36,11 @@ #include #include "collection/tree.h" +#include "collection/linear_alloc.h" #include "common/ngran_types.h" #include "rrc_types.h" //#include "PHY/phy_defs.h" #include "LAYER2/RLC/rlc.h" -#include "RRC/NR/nr_rrc_types.h" #include "NR_UE-MRDC-Capability.h" #include "NR_UE-NR-Capability.h" @@ -219,17 +219,6 @@ void *send_UE_status_notification(void *); #include "commonDef.h" -//-------- -typedef unsigned int uid_t; -#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((MAX_MOBILES_PER_ENB/8)/sizeof(unsigned int)) + 1) -typedef struct uid_linear_allocator_s { - unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; -} uid_allocator_t; - -//-------- - - - #define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT #define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) @@ -367,7 +356,7 @@ typedef struct UE_RRC_INFO_s { } __attribute__ ((__packed__)) UE_RRC_INFO; typedef struct UE_S_TMSI_s { - boolean_t presence; + bool presence; mme_code_t mme_code; m_tmsi_t m_tmsi; } __attribute__ ((__packed__)) UE_S_TMSI; @@ -668,8 +657,6 @@ typedef struct eNB_RRC_UE_s { int nr_capabilities_requested; } eNB_RRC_UE_t; -typedef uid_t ue_uid_t; - typedef struct rrc_eNB_ue_context_s { /* Tree related data */ RB_ENTRY(rrc_eNB_ue_context_s) entries; @@ -680,7 +667,7 @@ typedef struct rrc_eNB_ue_context_s { rnti_t ue_id_rnti; // another key for protocol layers but should not be used as a key for RB tree - ue_uid_t local_uid; + uid_t local_uid; /* UE id for initial connection to S1AP */ struct eNB_RRC_UE_s ue_context; @@ -762,7 +749,7 @@ typedef struct eNB_RRC_INST_s { char *node_name; uint32_t node_id; rrc_eNB_carrier_data_t carrier[MAX_NUM_CCs]; - uid_allocator_t uid_allocator; // for rrc_ue_head + uid_allocator_t uid_allocator; RB_HEAD(rrc_ue_tree_s, rrc_eNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti uint8_t HO_flag; uint8_t Nb_ue; @@ -931,7 +918,7 @@ typedef struct UE_RRC_INST_s { } UE_RRC_INST; typedef struct UE_PF_PO_s { - boolean_t enable_flag; /* flag indicate whether current object is used */ + bool enable_flag; /* flag indicate whether current object is used */ uint16_t ue_index_value; /* UE index value */ uint8_t PF_min; /* minimal value of Paging Frame (PF) */ uint8_t PO; /* Paging Occasion (PO) */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index ea98d3169d..8be30175e1 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -150,7 +150,7 @@ init_SI( LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL; LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); - if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { + if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == true) { LOG_A(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -266,7 +266,7 @@ init_SI( carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id], ctxt_pP->module_id, CC_id, - FALSE, + false, configuration ); AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); @@ -276,7 +276,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], ctxt_pP->module_id, - CC_id, TRUE, configuration); + CC_id, true, configuration); } } @@ -285,7 +285,7 @@ init_SI( AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB"); carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id, CC_id, - FALSE, + false, configuration ); LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23); @@ -295,7 +295,7 @@ init_SI( if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) { carrier->SIB23_BR = (uint8_t *) malloc16(64); AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB"); - carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, TRUE, configuration); + carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, true, configuration); } LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n", @@ -661,7 +661,7 @@ rrc_eNB_get_next_transaction_identifier( ////----------------------------------------------------------------------------- //{ // -// boolean_t reg = FALSE; +// bool reg = false; // module_id_t i; // // AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST); @@ -669,12 +669,12 @@ rrc_eNB_get_next_transaction_identifier( // for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { // if (RC.rrc[enb_mod_idP]->Info.UE_info[i] == UE_identity) { // // UE_identity already registered -// reg = TRUE; +// reg = true; // break; // } // } // -// if (reg == FALSE) { +// if (reg == false) { // return (UE_MODULE_INVALID); // } else // return (i); @@ -713,7 +713,7 @@ rrc_eNB_ue_context_stmsi_exist( m_tmsiP, mme_codeP, ue_context_p, ue_context_p->ue_context.rnti); - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { printf("=> S-TMSI %x, MME %x\n", ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code); @@ -976,28 +976,24 @@ rrc_eNB_free_UE( put_UE_in_freelist(enb_mod_idP, rnti, 1); } -void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) { +void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag) { eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; pthread_mutex_lock(&lock_ue_freelist); - UE_free_list_t *free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0; - free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1); - free_list->num_UEs--; - pthread_mutex_unlock(&lock_ue_freelist); -} - -void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { - UE_free_list_t *free_list = NULL; - eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - pthread_mutex_lock(&lock_ue_freelist); - free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; - free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; - free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 0; - free_list->num_UEs++; + LOG_I(PHY,"add ue %d in fre list, context flag: %d\n", rnti, removeFlag); + int i; + for (i=0; i < sizeofArray(eNB_MAC->UE_free_ctrl); i++) + if (eNB_MAC->UE_free_ctrl[i].rnti == 0) + break; + if (i==sizeofArray(eNB_MAC->UE_free_ctrl)) { + LOG_E(PHY,"List of UE to free is full\n"); + pthread_mutex_unlock(&lock_ue_freelist); + return; + } + eNB_MAC->UE_free_ctrl[i].rnti = rnti; + eNB_MAC->UE_free_ctrl[i].removeContextFlg = removeFlag; + eNB_MAC->UE_free_ctrl[i].raFlag = 0; eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti; eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++; - free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); pthread_mutex_unlock(&lock_ue_freelist); } @@ -1007,104 +1003,47 @@ extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); void release_UE_in_freeList(module_id_t mod_id) { - int i, j, CC_id, pdu_number; - protocol_ctxt_t ctxt; - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; PHY_VARS_eNB *eNB_PHY = NULL; - struct rrc_eNB_ue_context_s *ue_context_pP = NULL; eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - boolean_t remove_UEContext; - rnti_t rnti; - int head, tail, ue_num; pthread_mutex_lock(&lock_ue_freelist); - head = eNB_MAC->UE_free_list.head_freelist; - tail = eNB_MAC->UE_free_list.tail_freelist; - if(head == tail) { - pthread_mutex_unlock(&lock_ue_freelist); - return; - } - - if(tail < head) { - tail = head + eNB_MAC->UE_free_list.num_UEs; - } - - pthread_mutex_unlock(&lock_ue_freelist); - - for(ue_num = head; ue_num < tail; ue_num++) { - ue_num = ue_num % (NUMBER_OF_UE_MAX+1); - rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti; + for(int ue_num = 0; ue_num < sizeofArray(eNB_MAC->UE_free_ctrl) ; ue_num++) { + rnti_t rnti = eNB_MAC->UE_free_ctrl[ue_num].rnti; if(rnti != 0) { - remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg; + protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; int id; // clean ULSCH entries for rnti - id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); + id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); // clean DLSCH entries for rnti - id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); + id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); // clean UCI entries for rnti - for (i=0; iuci_vars[i].rnti == rnti) { LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } - /* - for (i=0; iulsch[i]; - - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } - - dlsch = eNB_PHY->dlsch[i][0]; - - if((dlsch != NULL) && (dlsch->rnti == rnti)) { - void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); - clean_eNb_dlsch(dlsch); - } - } - - ulsch = eNB_PHY->ulsch[i]; - - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } - - for (i=0; iuci_vars[i].rnti == rnti) { - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - */ - if (flexran_agent_get_rrc_xface(mod_id)) { - flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( - mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } - for(j = 0; j < 10; j++) { - ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; + for(int j = 0; j < 10; j++) { + nfapi_ul_config_request_body_t *ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; if(ul_req_tmp) { - pdu_number = ul_req_tmp->number_of_pdus; + int pdu_number = ul_req_tmp->number_of_pdus; for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || @@ -1126,7 +1065,8 @@ void release_UE_in_freeList(module_id_t mod_id) { } if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) { - rrc_mac_remove_ue(mod_id,rnti); + if (!eNB_MAC->UE_free_ctrl[ue_num].raFlag) + rrc_mac_remove_ue(mod_id,rnti); rrc_rlc_remove_ue(&ctxt); pdcp_remove_UE(&ctxt); } else { @@ -1139,19 +1079,20 @@ void release_UE_in_freeList(module_id_t mod_id) { itti_send_msg_to_task(TASK_CU_F1, mod_id, m); } - if(remove_UEContext) { - ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti); - + if(eNB_MAC->UE_free_ctrl[ue_num].removeContextFlg) { + struct rrc_eNB_ue_context_s *ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti); if(ue_context_pP) { + LOG_I(PHY, "remove RNTI %04x\n", rnti); rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id], (struct rrc_eNB_ue_context_s *) ue_context_pP); } } - LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti); - remove_UE_from_freelist(mod_id, rnti); + LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList ra context: %d\n", rnti, eNB_MAC->UE_free_ctrl[ue_num].raFlag); + eNB_MAC->UE_free_ctrl[ue_num].rnti = 0; } } + pthread_mutex_unlock(&lock_ue_freelist); } int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t *ue_context_pP) { @@ -1678,7 +1619,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.rnti = ctxt_pP->rnti; if (EPC_MODE_ENABLED) { - uint8_t send_security_mode_command = FALSE; + uint8_t send_security_mode_command = false; rrc_pdcp_config_security( ctxt_pP, ue_context_pP, @@ -2332,7 +2273,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co // PDCP PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; break; default : @@ -2590,7 +2531,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; break; default : @@ -2951,7 +2892,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -3347,7 +3288,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.present = LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.present = LTE_ThresholdNR_r15_PR_nr_RSRP_r15; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.choice.nr_RSRP_r15 = 0; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = FALSE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = false; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.hysteresis = 2; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms80; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.maxReportCells = 4; @@ -3361,9 +3302,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 == NULL) exit(1); - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = TRUE; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = TRUE; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = TRUE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = true; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = true; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = true; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_NR); LOG_A(RRC, "Generating RRCCConnectionReconfigurationRequest (NRUE Measurement Report Request).\n"); } @@ -3714,7 +3655,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = 0; // FALSE #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -5052,7 +4993,7 @@ check_handovers( && ue_context_p->ue_context.handover_info != NULL && ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) { MessageDef *msg_p; - int result; + bool result; protocol_ctxt_t ctxt; do { @@ -5090,7 +5031,7 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode, NULL, NULL ); - if (result != TRUE) { + if (result != true) { LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n"); } else { LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n"); @@ -5158,7 +5099,7 @@ check_handovers( GTPV1U_ENB_END_MARKER_IND (msg_p).mode, NULL, NULL ); - if (result != TRUE) { + if (result != true) { LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n"); } else { LOG_D(RRC, "target enb send spgw buffer to PDCP!\n"); @@ -5390,7 +5331,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = 0; // FALSE #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -6280,10 +6221,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc ctxt_pP, ue_context_p, ue_context_p->ue_context.kenb); - rrc_pdcp_config_security( - ctxt_pP, - ue_context_p, - FALSE); + rrc_pdcp_config_security(ctxt_pP, ue_context_p, false); } // Add a new user (called during the HO procedure) @@ -6361,9 +6299,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is received + if (UE_scheduling_control->cdrx_waiting_ack == true) { + UE_scheduling_control->cdrx_waiting_ack = false; + UE_scheduling_control->cdrx_configured = true; // Set to TRUE when RRC Connection Reconfiguration is received LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } } @@ -6627,7 +6565,7 @@ rrc_eNB_generate_RRCConnectionSetup( ) //----------------------------------------------------------------------------- { - boolean_t is_mtc = ctxt_pP->brOption; + bool is_mtc = ctxt_pP->brOption; LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; @@ -7249,6 +7187,7 @@ rrc_eNB_decode_ccch( LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti); if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + LOG_I(PHY, "remove RNTI %04x\n", ue_context_p->ue_context.rnti); rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); } else { MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); @@ -7284,7 +7223,7 @@ rrc_eNB_decode_ccch( LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = TRUE; + ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = true; ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code; ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi; } else { @@ -8766,7 +8705,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0) { if (fd) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { fprintf(fd,"RRC UE rnti %x: S-TMSI %x failure timer %d/8\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 575a38ee3d..64b5594dd9 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -84,23 +84,20 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( } //------------------------------------------------------------------------------ -boolean_t -gtpv_data_req( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, - const pdcp_transmission_mode_t modeP, - uint32_t task_id -) +bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id) //------------------------------------------------------------------------------ { if(sdu_sizeP == 0) { LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0"); - return FALSE; + return false; } LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP); MessageDef *message_p; @@ -129,7 +126,7 @@ gtpv_data_req( GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } else if (task_id == TASK_END_MARKER){ LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n"); @@ -152,23 +149,22 @@ gtpv_data_req( GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } LOG_E(RRC, "Impossible state\n"); - return FALSE; + return false; } -boolean_t gtpv_data_req_new ( - protocol_ctxt_t *ctxt, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool gtpv_data_req_new(protocol_ctxt_t *ctxt, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { int task; if (sdu_buffer_sizeP==0) diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index ab789099ca..f991cbd5f6 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -60,16 +60,13 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( rrc_eNB_ue_context_t* ue_context_pP ); -boolean_t -gtpv_data_req( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, - const pdcp_transmission_mode_t modeP, - uint32_t task_id -); +bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id); #endif /* RRC_ENB_GTPV1U_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index f24c9ab1b6..aefbc01831 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -402,15 +402,13 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte *\param mod_id Instance ID of eNB. *\param ue_index Instance ID of UE in the eNB. *\param security_capabilities The security capabilities received from S1AP. - *\return TRUE if at least one algorithm has been changed else FALSE. + *\return true if at least one algorithm has been changed else false. */ int -rrc_eNB_process_security( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - security_capabilities_t *security_capabilities_pP -) { - boolean_t changed = FALSE; +rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + security_capabilities_t *security_capabilities_pP) { + bool changed = false; LTE_CipheringAlgorithm_r12_t cipheringAlgorithm; e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ @@ -428,14 +426,14 @@ rrc_eNB_process_security( if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; - changed = TRUE; + changed = true; } integrityProtAlgorithm = rrc_eNB_select_integrity (ue_context_pP->ue_context.security_capabilities.integrity_algorithms); if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; - changed = TRUE; + changed = true; } LOG_I (RRC, "[eNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", @@ -532,7 +530,7 @@ rrc_pdcp_config_security( pdcp_p, DCCH, DCCH+2, - (send_security_mode_command == TRUE) ? + (send_security_mode_command == true) ? 0 | (ue_context_pP->ue_context.integrity_algorithm << 4) : (ue_context_pP->ue_context.ciphering_algorithm ) | (ue_context_pP->ue_context.integrity_algorithm << 4), @@ -960,12 +958,12 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char ue_context_p, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); { - uint8_t send_security_mode_command = TRUE; + uint8_t send_security_mode_command = true; #ifndef EXMIMO_IOT if ((ue_context_p->ue_context.ciphering_algorithm == SecurityAlgorithmConfig__cipheringAlgorithm_eea0) && (ue_context_p->ue_context.integrity_algorithm == INTEGRITY_ALGORITHM_NONE)) { - send_security_mode_command = FALSE; + send_security_mode_command = false; } #endif @@ -978,7 +976,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char rrc_eNB_generate_SecurityModeCommand ( &ctxt, ue_context_p); - send_security_mode_command = FALSE; + send_security_mode_command = false; // apply ciphering after RRC security command mode rrc_pdcp_config_security( &ctxt, @@ -1414,19 +1412,19 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam /* Save e RAB information for later */ { int j; - boolean_t is_treated[S1AP_MAX_E_RAB] = {FALSE}; + bool is_treated[S1AP_MAX_E_RAB] = {false}; uint8_t nb_of_failed_e_rabs = 0; // keep the previous bearer // the index for the rec for (i = 0; i < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; i++) { - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { // already treated continue; } for (j = i+1; j < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; j++) { - if (is_treated[j] == FALSE && + if (is_treated[j] == false && S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[j].status = E_RAB_STATUS_NEW; @@ -1434,12 +1432,12 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[j].cause = S1AP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_e_rab[j].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; - is_treated[j] = TRUE; + is_treated[i] = true; + is_treated[j] = true; } } - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id; @@ -1456,7 +1454,7 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NAS; ue_context_p->ue_context.modify_e_rab[i].cause_value = 3;//S1ap_CauseNas_unspecified; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; + is_treated[i] = true; continue; } @@ -1474,19 +1472,19 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.buffer = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.buffer; ue_context_p->ue_context.modify_e_rab[i].param.sgw_addr = ue_context_p->ue_context.e_rab[j].param.sgw_addr; ue_context_p->ue_context.modify_e_rab[i].param.gtp_teid = ue_context_p->ue_context.e_rab[j].param.gtp_teid; - is_treated[i] = TRUE; + is_treated[i] = true; break; } } - if (is_treated[i] == FALSE) { + if (is_treated[i] == false) { // handle Unknown E-RAB ID ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id; ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_e_rab[i].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; + is_treated[i] = true; } } @@ -1824,8 +1822,8 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint8_t i = 0; for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) - || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { + if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) + || (UE_PF_PO[CC_id][i].enable_flag != true)) { /* set T = min(Tc,Tue) */ UE_PF_PO[CC_id][i].T = T; /* set UE_ID */ @@ -1845,12 +1843,12 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); } - if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { + if (UE_PF_PO[CC_id][i].enable_flag == true) { //paging exist UE log LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } else { /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = TRUE; + UE_PF_PO[CC_id][i].enable_flag = true; //paging new UE log LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c index 0d262064b5..c9077bfb24 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.c +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.c @@ -37,64 +37,6 @@ #include "rrc_eNB_UE_context.h" -//------------------------------------------------------------------------------ -void -uid_linear_allocator_init( - uid_allocator_t *const uid_pP -) -//------------------------------------------------------------------------------ -{ - memset(uid_pP, 0, sizeof(uid_allocator_t)); -} - -//------------------------------------------------------------------------------ -uid_t -uid_linear_allocator_new( - eNB_RRC_INST *const rrc_instance_pP -) -//------------------------------------------------------------------------------ -{ - unsigned int i; - unsigned int bit_index = 1; - uid_t uid = 0; - uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; - - for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { - if (uia_p->bitmap[i] != UINT_MAX) { - bit_index = 1; - uid = 0; - - while ((uia_p->bitmap[i] & bit_index) == bit_index) { - bit_index = bit_index << 1; - uid += 1; - } - - uia_p->bitmap[i] |= bit_index; - return uid + (i*sizeof(unsigned int)*8); - } - } - - return UINT_MAX; -} - - -//------------------------------------------------------------------------------ -void -uid_linear_allocator_free( - eNB_RRC_INST *rrc_instance_pP, - uid_t uidP -) -//------------------------------------------------------------------------------ -{ - unsigned int i = uidP/sizeof(unsigned int)/8; - unsigned int bit = uidP % (sizeof(unsigned int) * 8); - unsigned int value = ~(0x00000001 << bit); - - if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { - rrc_instance_pP->uid_allocator.bitmap[i] &= value; - } -} - //------------------------------------------------------------------------------ int rrc_eNB_compare_ue_rnti_id( @@ -134,7 +76,7 @@ rrc_eNB_allocate_new_UE_context( } memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s)); - new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP); + new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; @@ -210,7 +152,7 @@ void rrc_eNB_remove_ue_context( RB_REMOVE(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP); - uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid); free(ue_context_pP); rrc_instance_pP->Nb_ue --; LOG_I(RRC, diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.h b/openair2/RRC/LTE/rrc_eNB_UE_context.h index c6420ca936..89469529df 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.h +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.h @@ -34,27 +34,6 @@ #include "COMMON/platform_types.h" #include "rrc_defs.h" - -void -uid_linear_allocator_init( - uid_allocator_t* const uid_pP -); - -uid_t -uid_linear_allocator_new( - eNB_RRC_INST* rrc_instance_pP -); - - -void -uid_linear_allocator_free( - eNB_RRC_INST* rrc_instance_pP, - uid_t uidP -); - - - - int rrc_eNB_compare_ue_rnti_id( struct rrc_eNB_ue_context_s* c1_pP, struct rrc_eNB_ue_context_s* c2_pP diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index f0456005f5..7bd3fbf758 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -457,7 +457,7 @@ mac_rrc_data_ind( const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP, - const boolean_t brOption + const bool brOption ); int8_t @@ -685,7 +685,7 @@ extern RRC_release_list_t rrc_release_info; extern pthread_mutex_t lock_ue_freelist; void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti); -void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag); +void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag); void release_UE_in_freeList(module_id_t mod_id); /** @}*/ diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 952f32fb10..67e06914ef 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -49,102 +49,6 @@ extern RAN_CONTEXT_t RC; -int generate_pdcch_ConfigSIB1(NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1, - long ssbSubcarrierSpacing, - long subCarrierSpacingCommon, - channel_bandwidth_t min_channel_bw) { - - nr_ssb_and_cset_mux_pattern_type_t mux_pattern = 0; - - switch (ssbSubcarrierSpacing) { - - case NR_SubcarrierSpacing_kHz15: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_1_NUM_INDEXES; - mux_pattern = table_38213_13_1_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_2_NUM_INDEXES; - mux_pattern = table_38213_13_2_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz30: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { - - if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_3_NUM_INDEXES; - mux_pattern = table_38213_13_3_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (min_channel_bw == bw_40MHz) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_5_NUM_INDEXES; - mux_pattern = table_38213_13_5_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid min_bandwidth\n"); - } - - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { - - if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_4_NUM_INDEXES; - mux_pattern = table_38213_13_4_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (min_channel_bw == bw_40MHz) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_6_NUM_INDEXES; - mux_pattern = table_38213_13_6_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid min_bandwidth\n"); - } - - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz120: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_7_NUM_INDEXES; - mux_pattern = table_38213_13_7_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_8_NUM_INDEXES; - mux_pattern = table_38213_13_8_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz240: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_9_NUM_INDEXES; - mux_pattern = table_38213_13_9_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_10_NUM_INDEXES; - mux_pattern = table_38213_13_10_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - default: - AssertFatal(true,"Invalid ssbSubcarrierSpacing\n"); - break; - } - - - frequency_range_t frequency_range = FR1; - if(ssbSubcarrierSpacing>=60) { - frequency_range = FR2; - } - - pdcch_ConfigSIB1->searchSpaceZero = 0; - if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR1){ - pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_11_NUM_INDEXES; - } - if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR2){ - pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_12_NUM_INDEXES; - } - - return 0; -} int nr_rrc_mac_remove_ue(module_id_t mod_idP, @@ -168,7 +72,7 @@ nr_rrc_data_req( { if(sdu_sizeP == 255) { LOG_D(RRC,"sdu_sizeP == 255"); - return FALSE; + return false; } MessageDef *message_p; @@ -204,7 +108,7 @@ nr_rrc_data_req( if (ctxt_pP->enb_flag && NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) pdcp_run(ctxt_pP); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, @@ -227,14 +131,6 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier; NR_BCCH_BCH_Message_t *mib = &carrier->mib; - // Currently we are getting the pdcch_ConfigSIB1 from the configuration file. - // Uncomment this function for a dynamic pdcch_ConfigSIB1. - //channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1 - //generate_pdcch_ConfigSIB1(carrier->pdcch_ConfigSIB1, - // *carrier->servingcellconfigcommon->ssbSubcarrierSpacing, - // carrier->mib.message.choice.mib->subCarrierSpacingCommon, - // min_channel_bw); - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero; mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero; @@ -306,74 +202,6 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, return 0; } -int8_t nr_mac_rrc_data_ind(const module_id_t module_idP, - const int CC_id, - const frame_t frameP, - const sub_frame_t sub_frameP, - const int UE_id, - const rnti_t rntiP, - const rb_id_t srb_idP, - const uint8_t *sduP, - const sdu_size_t sdu_lenP, - const boolean_t brOption) { - - if (NODE_IS_DU(RC.nrrrc[module_idP]->node_type)) { - LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %ld length %d for UE id %d RNTI %x \n", - module_idP, srb_idP, sdu_lenP, UE_id, rntiP); - - // Generate DUtoCURRCContainer - // call do_RRCSetup like full procedure and extract masterCellGroup - NR_CellGroupConfig_t cellGroupConfig; - NR_ServingCellConfigCommon_t *scc=RC.nrrrc[module_idP]->carrier.servingcellconfigcommon; - NR_ServingCellConfig_t *servingcellconfigdedicated = RC.nrrrc[module_idP]->configuration.scd; - memset(&cellGroupConfig,0,sizeof(cellGroupConfig)); - - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_idP]); - ue_context_p->ue_id_rnti = rntiP; - ue_context_p->ue_context.rnti = rntiP; - ue_context_p->ue_context.random_ue_identity = rntiP; - ue_context_p->ue_context.Srb0.Active = 1; - RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_idP]->rrc_ue_head, ue_context_p); - - fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc,servingcellconfigdedicated,&RC.nrrrc[module_idP]->configuration); - - MessageDef* tmp=itti_alloc_new_message_sized(TASK_RRC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE, sizeof(f1ap_initial_ul_rrc_message_t) + sdu_lenP); - f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(tmp); - - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - (void *)&cellGroupConfig, - msg->du2cu_rrc_container, - F1AP_MAX_DU2CU_RRC_LENGTH); - - if (enc_rval.encoded == -1) { - LOG_E(F1AP,"Could not encoded cellGroupConfig, failed element %s\n",enc_rval.failed_type->name); - exit(-1); - } - /* do ITTI message */ - msg->du2cu_rrc_container_length = (enc_rval.encoded+7)/8; - msg->crnti=rntiP; - msg->rrc_container=(uint8_t*) (msg+1); // Made extra room after the struct with itti_alloc_msg_sized() - memcpy(msg->rrc_container, sduP, sdu_lenP); - msg->rrc_container_length=sdu_lenP; - itti_send_msg_to_task(TASK_DU_F1, 0, tmp); - return(0); - } - - protocol_ctxt_t ctxt; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP,0); - - if((srb_idP & RAB_OFFSET) == CCCH) { - LOG_D(NR_RRC, "[gNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP); - ctxt.brOption = brOption; - if (sdu_lenP > 0) { - nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, NULL, CC_id); - } - } - - return 0; -} - void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, const int CC_idP, const frame_t frameP, diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 49de6cdb03..6aaa96a8e7 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -42,6 +42,7 @@ #include #include +#include "executables/softmodem-common.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "asn1_msg.h" #include "../nr_rrc_proto.h" @@ -198,8 +199,7 @@ int xer_nr_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { asn_enc_rval_t enc_rval; - rrc_gNB_carrier_data_t *carrier = &rrc->carrier; - const gNB_RrcConfigurationReq *configuration = &rrc->configuration; + rrc_gNB_carrier_data_t *carrier = &rrc->carrier; NR_BCCH_BCH_Message_t *mib = &carrier->mib; NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon; @@ -226,11 +226,14 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band<100?FR1:FR2; - int ssb_subcarrier_offset; - if(frequency_range == FR1) - ssb_subcarrier_offset = (configuration->ssb_SubcarrierOffset<24) ? (configuration->ssb_SubcarrierOffset<<*scc->ssbSubcarrierSpacing) : configuration->ssb_SubcarrierOffset; - else - ssb_subcarrier_offset = configuration->ssb_SubcarrierOffset; + int ssb_subcarrier_offset = 31; // default value for NSA + if (get_softmodem_params()->sa) { + uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); + int scs_scaling = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1; + ssb_subcarrier_offset = (absolute_diff/scs_scaling)%24; + if(frequency_range == FR2) + ssb_subcarrier_offset >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for now) + } mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset&15; /* @@ -303,11 +306,10 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { return((enc_rval.encoded+7)/8); } -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, - gNB_RrcConfigurationReq *configuration - ) { - asn_enc_rval_t enc_rval; +uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, + gNB_RrcConfigurationReq *configuration) { + asn_enc_rval_t enc_rval; NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); carrier->siblock1 = sib1_message; sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; @@ -343,7 +345,6 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, if(configuration->mnc_digit_length[i] == 3) { asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc0); *mnc0=(configuration->mnc[i]/100)%10; - mnc/=10; } asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc1); *mnc1=(mnc/10)%10; @@ -658,12 +659,9 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, (void *)sib1_message, carrier->SIB1, NR_MAX_SIB_LENGTH/8); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - if (enc_rval.encoded==-1) { - return(-1); - } + AssertFatal(enc_rval.encoded <= NR_MAX_SIB_LENGTH, "ASN1 encoded length %zd bits. 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", enc_rval.encoded); return((enc_rval.encoded+7)/8); } @@ -986,35 +984,10 @@ uint8_t do_RRCReject(uint8_t Mod_id, return((enc_rval.encoded+7)/8); } -// TODO: Implement to b_SRS = 1 and b_SRS = 2 -long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS) { - - if(b_SRS>0) { - LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); - return 0; // This c_srs is always valid - } - - const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, - 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, - 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, - 256, 264, 272, 272, 272 }; - - long c_srs = 0; - uint16_t m = 4; - for(int c = 1; c<64; c++) { - if(m_SRS[c]>m && m_SRS[c]bwp_Common->genericParameters.cyclicPrefix = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix; } + int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); + ubwp->bwp_Common->rach_ConfigCommon = NULL; ubwp->bwp_Common->pusch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; ubwp->bwp_Common->pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; @@ -1192,125 +1167,17 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->choice.setup=pucch_Config; + pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=0; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=1; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - pucchres0->pucch_ResourceId=0; - pucchres0->startingPRB=(8+uid) % (curr_bwp/2); - LOG_D(NR_RRC, "pucchres0->startPRB %ld uid %d curr_bwp %d\n", pucchres0->startingPRB, uid, curr_bwp); - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - pucchres2->pucch_ResourceId=1; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); - // PUCCH config - Scheduling request configuration - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; // 40 slot period - // note: make sure that there is no issue here. Later choose the RNTI accordingly. - // Here we would be limited to 3 UEs on this resource (1 1/2 Frames 30 kHz SCS, 5 ms TDD periodicity => slots 7,8,9). - // This should be a temporary resource until the first RRCReconfiguration gives new pucch resources. - // Check for above configuration and exit for now if it is not the case - AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, - "SCS != 30kHz\n"); - AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5, - "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 0; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - pucch_Config->schedulingRequestResourceToReleaseList=NULL; - - pucch_Config->multi_CSI_PUCCH_ResourceList=NULL; - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - AssertFatal(configuration->minRXTXTIME >=2 && configuration->minRXTXTIME <7, "check minRXTXTIME %d\n",configuration->minRXTXTIME); - *delay[i] = i+configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); - pucch_Config->spatialRelationInfoToReleaseList=NULL; - pucch_Config->pucch_PowerControl=calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = 0; - pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); - NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); - p00->p0_PUCCH_Id=1; - p00->p0_PUCCH_Value = 0; - ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); - pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; + scheduling_request_config(scc, pucch_Config); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); // PUSCH config ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); @@ -1464,8 +1331,8 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, void fill_initial_SpCellConfig(int uid, NR_SpCellConfig_t *SpCellConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration) { // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4. @@ -1490,81 +1357,11 @@ void fill_initial_SpCellConfig(int uid, initialUplinkBWP->pucch_Config->choice.setup=pucch_Config; pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=0; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=1; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); - pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - // configure one single PUCCH0 opportunity for initial connection procedure - // one symbol (13) - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - pucchres0->pucch_ResourceId=0; - //pucchres0->startingPRB=0; - pucchres0->startingPRB=(8+uid) % (curr_bwp/2); - LOG_D(NR_RRC, "pucchres0->startPRB %ld uid %d curr_bwp %d\n", pucchres0->startingPRB, uid, curr_bwp); - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - pucchres2->pucch_ResourceId=1; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config)); initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -1638,106 +1435,13 @@ void fill_initial_SpCellConfig(int uid, pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; + // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - initialUplinkBWP->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; - NR_SRS_Config_t *srs_Config = calloc(1,sizeof(*srs_Config)); - initialUplinkBWP->srs_Config->choice.setup=srs_Config; - srs_Config->srs_ResourceSetToReleaseList=NULL; - srs_Config->srs_ResourceSetToAddModList=calloc(1,sizeof(*srs_Config->srs_ResourceSetToAddModList)); - NR_SRS_ResourceSet_t *srs_resset0=calloc(1,sizeof(*srs_resset0)); - srs_resset0->srs_ResourceSetId = 0; - srs_resset0->srs_ResourceIdList=calloc(1,sizeof(*srs_resset0->srs_ResourceIdList)); - NR_SRS_ResourceId_t *srs_resset0_id=calloc(1,sizeof(*srs_resset0_id)); - *srs_resset0_id=0; - ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id); - srs_Config->srs_ResourceToReleaseList=NULL; + config_srs(initialUplinkBWP->srs_Config, scc, uid, 0); - if (configuration->do_SRS) { - srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_periodic; - srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic)); - srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL; - } else { - srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_aperiodic; - srs_resset0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic)); - srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger=1; - srs_resset0->resourceType.choice.aperiodic->csi_RS=NULL; - srs_resset0->resourceType.choice.aperiodic->slotOffset= calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic->slotOffset)); - *srs_resset0->resourceType.choice.aperiodic->slotOffset=2; - srs_resset0->resourceType.choice.aperiodic->ext1=NULL; - } + scheduling_request_config(scc, pucch_Config); - srs_resset0->usage=NR_SRS_ResourceSet__usage_codebook; - srs_resset0->alpha = calloc(1,sizeof(*srs_resset0->alpha)); - *srs_resset0->alpha = NR_Alpha_alpha1; - srs_resset0->p0=calloc(1,sizeof(*srs_resset0->p0)); - *srs_resset0->p0=-80; - srs_resset0->pathlossReferenceRS=NULL; - srs_resset0->srs_PowerControlAdjustmentStates=NULL; - ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceSetToAddModList->list,srs_resset0); - srs_Config->srs_ResourceToReleaseList=NULL; - srs_Config->srs_ResourceToAddModList=calloc(1,sizeof(*srs_Config->srs_ResourceToAddModList)); - NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); - srs_res0->srs_ResourceId=0; - srs_res0->nrofSRS_Ports=NR_SRS_Resource__nrofSRS_Ports_port1; - srs_res0->ptrs_PortIndex=NULL; - srs_res0->transmissionComb.present=NR_SRS_Resource__transmissionComb_PR_n2; - srs_res0->transmissionComb.choice.n2=calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); - srs_res0->transmissionComb.choice.n2->combOffset_n2=0; - srs_res0->transmissionComb.choice.n2->cyclicShift_n2=0; - srs_res0->resourceMapping.startPosition = 2 + uid%2; - srs_res0->resourceMapping.nrofSymbols=NR_SRS_Resource__resourceMapping__nrofSymbols_n1; - srs_res0->resourceMapping.repetitionFactor=NR_SRS_Resource__resourceMapping__repetitionFactor_n1; - srs_res0->freqDomainPosition=0; - srs_res0->freqDomainShift=0; - srs_res0->freqHopping.b_SRS=0; - srs_res0->freqHopping.b_hop=0; - srs_res0->freqHopping.c_SRS = rrc_get_max_nr_csrs( - NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275), - srs_res0->freqHopping.b_SRS); - srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither; - - if (configuration->do_SRS) { - srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic; - srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic)); - srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160; - srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.choice.sl160 = 17 + (uid>1)*10; // 17/17/.../147/157 are mixed slots - } else { - srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_aperiodic; - srs_res0->resourceType.choice.aperiodic=calloc(1,sizeof(*srs_res0->resourceType.choice.aperiodic)); - } - - srs_res0->sequenceId=40; - srs_res0->spatialRelationInfo=calloc(1,sizeof(*srs_res0->spatialRelationInfo)); - srs_res0->spatialRelationInfo->servingCellId=NULL; - srs_res0->spatialRelationInfo->referenceSignal.present=NR_SRS_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - srs_res0->spatialRelationInfo->referenceSignal.choice.csi_RS_Index=0; - ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0); - - // configure Scheduling request - // 40 slot period - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; - AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, - "SCS != 30kHz\n"); - - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 0; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - AssertFatal(configuration->minRXTXTIME >= 2 && configuration->minRXTXTIME < 7, - "minRXTXTIME is %d but should be within [2,7)\n", configuration->minRXTXTIME); - *delay[i] = i + configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); SpCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->initialDownlinkBWP)); NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP; @@ -1799,13 +1503,13 @@ void fill_initial_SpCellConfig(int uid, bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); - *bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1; - bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation = NR_PDSCH_Config__resourceAllocation_resourceAllocationType1; - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = - calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); - *bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; + *bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1; + bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation = NR_PDSCH_Config__resourceAllocation_resourceAllocationType1; + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = + calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); + *bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); NR_TCI_State_t *tcic; @@ -1886,14 +1590,13 @@ void fill_initial_SpCellConfig(int uid, csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires0); - NR_CSI_ResourceConfig_t *csires1 = calloc(1,sizeof(*csires1)); csires1->csi_ResourceConfigId=1; csires1->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList)); NR_CSI_SSB_ResourceSetId_t *ssbres00 = calloc(1,sizeof(*ssbres00)); - *ssbres00 = 0; + *ssbres00 = 0; ASN_SEQUENCE_ADD(&csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list,ssbres00); csires1->bwp_Id = 0; csires1->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -1913,8 +1616,8 @@ void fill_initial_SpCellConfig(int uid, } NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1)); - pucchcsires1->uplinkBandwidthPartId=0; - pucchcsires1->pucch_Resource=1; + pucchcsires1->uplinkBandwidthPartId = 0; + pucchcsires1->pucch_Resource = *pucch_Config->resourceSetToAddModList->list.array[1]->resourceList.list.array[0]; csi_MeasConfig->csi_ReportConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ReportConfigToAddModList)); csi_MeasConfig->csi_ReportConfigToReleaseList = NULL; if (pdsch_AntennaPorts > 1) { @@ -2010,6 +1713,7 @@ void fill_initial_SpCellConfig(int uid, csirep2->ext1 = NULL; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep2); } + pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; pdsch_servingcellconfig->xOverhead = NULL; pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); @@ -2139,7 +1843,7 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR return rlc_BearerConfig; } -void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority ) { +void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority) { cellGroupConfig->cellGroupId = 0; cellGroupConfig->rlc_BearerToReleaseList = NULL; @@ -2163,16 +1867,35 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr } void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, + const int uid, NR_UE_NR_Capability_t *uecap, const gNB_RrcConfigurationReq* configuration) { NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig; + if (SpCellConfig == NULL) return; NR_ServingCellConfigCommon_t *scc = configuration ? configuration->scc : NULL; - // Set DL MCS table if(scc) { + + // SRS configuration + if (configuration->do_SRS && + SpCellConfig && + SpCellConfig->spCellConfigDedicated && + SpCellConfig->spCellConfigDedicated->uplinkConfig && + SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { + if (!SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config) { + SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config = + calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config)); + } + config_srs(SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config, + scc, + uid, + configuration->do_SRS); + } + + // Set DL MCS table NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP; set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing, configuration->force_256qam_off ? NULL : uecap, SpCellConfig, bwp_Dedicated, scc); @@ -2184,14 +1907,14 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, SpCellConfig, bwp->bwp_Dedicated, scc); } } - } + } } void fill_initial_cellGroupConfig(int uid, NR_CellGroupConfig_t *cellGroupConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration) { NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL; @@ -2208,36 +1931,33 @@ void fill_initial_cellGroupConfig(int uid, cellGroupConfig->rlc_BearerToReleaseList = NULL; /* mac CellGroup Config */ - if (1) { - mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig)); - if (1) { - mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); - mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); - struct NR_SchedulingRequestToAddMod *schedulingrequestlist; - schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); - schedulingrequestlist->schedulingRequestId = 0; - schedulingrequestlist->sr_ProhibitTimer = CALLOC(1,sizeof(*schedulingrequestlist->sr_ProhibitTimer)); - *(schedulingrequestlist->sr_ProhibitTimer) = 0; - schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; - ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); - } - mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); - mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; - mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; - mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config)); - mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; - mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); - struct NR_TAG *tag=calloc(1,sizeof(*tag)); - tag->tag_Id = 0; - tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; - ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); - mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config)); - mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; - mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); - mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10; - mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10; - mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1; - } + mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig)); + + mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; + mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config)); + mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; + mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); + struct NR_TAG *tag=calloc(1,sizeof(*tag)); + tag->tag_Id = 0; + tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; + ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); + mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config)); + mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; + mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); + mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1; + + mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); + mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); + struct NR_SchedulingRequestToAddMod *schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); + schedulingrequestlist->schedulingRequestId = 0; + schedulingrequestlist->sr_ProhibitTimer = NULL; + schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; + ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); + cellGroupConfig->mac_CellGroupConfig = mac_CellGroupConfig; physicalCellGroupConfig = calloc(1,sizeof(*physicalCellGroupConfig)); @@ -2247,7 +1967,7 @@ void fill_initial_cellGroupConfig(int uid, cellGroupConfig->physicalCellGroupConfig = physicalCellGroupConfig; cellGroupConfig->spCellConfig = calloc(1,sizeof(*cellGroupConfig->spCellConfig)); - + fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,servingcellconfigdedicated,configuration); cellGroupConfig->sCellToAddModList = NULL; @@ -2255,13 +1975,14 @@ void fill_initial_cellGroupConfig(int uid, } //------------------------------------------------------------------------------ -int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, - uint8_t *const buffer, - const uint8_t transaction_id, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, - const gNB_RrcConfigurationReq *configuration) +int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t *const buffer, + const uint8_t transaction_id, + const uint8_t *masterCellGroup, + int masterCellGroup_len, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const gNB_RrcConfigurationReq *configuration) //------------------------------------------------------------------------------ { asn_enc_rval_t enc_rval; @@ -2271,7 +1992,6 @@ int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, NR_SRB_ToAddMod_t *SRB1_config = NULL; NR_PDCP_Config_t *pdcp_Config = NULL; NR_CellGroupConfig_t *cellGroupConfig = NULL; - char masterCellGroup_buf[3000]; AssertFatal(ue_context_pP != NULL,"ue_context_p is null\n"); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -2314,38 +2034,14 @@ int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, ie->radioBearerConfig.securityConfig = NULL; /****************************** masterCellGroup ******************************/ - /* TODO */ - if (masterCellGroup_from_DU) { - memcpy(&ie->masterCellGroup,masterCellGroup_from_DU,sizeof(*masterCellGroup_from_DU)); - // decode masterCellGroup OCTET_STRING received from DU and place in ue context - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)masterCellGroup_from_DU->buf, - masterCellGroup_from_DU->size, 0, 0); - } - else { - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_initial_cellGroupConfig(ue_context_pP->local_uid,cellGroupConfig,scc,servingcellconfigdedicated,configuration); - - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - (void *)cellGroupConfig, - masterCellGroup_buf, - 3000); - - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } - - if (OCTET_STRING_fromBuf(&ie->masterCellGroup, masterCellGroup_buf, (enc_rval.encoded+7)/8) == -1) { - LOG_E(NR_RRC, "fatal: OCTET_STRING_fromBuf failed\n"); - return -1; - } - } + DevAssert(masterCellGroup && masterCellGroup_len > 0); + ie->masterCellGroup.buf = malloc(masterCellGroup_len); + AssertFatal(ie->masterCellGroup.buf != NULL, "could not allocate memory for masterCellGroup\n"); + memcpy(ie->masterCellGroup.buf, masterCellGroup, masterCellGroup_len); + ie->masterCellGroup.size = masterCellGroup_len; + // decode masterCellGroup OCTET_STRING received from DU and place in ue context + uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, (void **)&cellGroupConfig, masterCellGroup, masterCellGroup_len, 0, 0); ue_p->masterCellGroup = cellGroupConfig; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -2629,6 +2325,7 @@ int16_t do_RRCReconfiguration( if(cellGroupConfig!=NULL){ update_cellGroupConfig(cellGroupConfig, + ue_context_pP->local_uid, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index e79f79493d..1d6be68f5c 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -73,9 +73,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc, @param carrier pointer to Carrier information @param configuration Pointer Configuration Request structure @return size of encoded bit stream in bytes*/ -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, - gNB_RrcConfigurationReq *configuration - ); +uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); @@ -103,17 +101,18 @@ uint8_t do_RRCReject(uint8_t Mod_id, void fill_initial_SpCellConfig(int uid, NR_SpCellConfig_t *SpCellConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration); void fill_initial_cellGroupConfig(int uid, NR_CellGroupConfig_t *cellGroupConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration); void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, + const int uid, NR_UE_NR_Capability_t *uecap, const gNB_RrcConfigurationReq *configuration); @@ -125,13 +124,14 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t nb_bearers_to_setup, long *priority); -int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, - uint8_t *const buffer, - const uint8_t transaction_id, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, - const gNB_RrcConfigurationReq *configuration); +int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t *const buffer, + const uint8_t transaction_id, + const uint8_t *masterCellGroup, + int masterCellGroup_len, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const gNB_RrcConfigurationReq *configuration); uint8_t do_NR_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h new file mode 100644 index 0000000000..1943490cd6 --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -0,0 +1,34 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef MAC_RRC_DL_H +#define MAC_RRC_DL_H + +#include "platform_types.h" +#include "f1ap_messages_types.h" + +typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); + +struct nr_mac_rrc_dl_if_s; +void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); +void mac_rrc_dl_f1ap_init(struct nr_mac_rrc_dl_if_s *mac_rrc); + +#endif /* MAC_RRC_DL_H */ diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c new file mode 100644 index 0000000000..5c8d9d9d5b --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -0,0 +1,37 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_rrc_defs.h" + +#include "mac_rrc_dl.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" + +static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* TODO how to manage inter-thread communication? */ + + dl_rrc_message(module_id, dl_rrc); +} + +void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) +{ + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; +} diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c new file mode 100644 index 0000000000..40f3b4b6ea --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -0,0 +1,44 @@ +/* + * 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: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "mac_rrc_dl.h" +#include "nr_rrc_defs.h" + +static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* TODO call F1AP function directly? no real-time constraint here */ + + MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); + f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); + *msg = *dl_rrc; + if (dl_rrc->rrc_container) { + msg->rrc_container = malloc(dl_rrc->rrc_container_length); + AssertFatal(msg->rrc_container != NULL, "out of memory\n"); + msg->rrc_container_length = dl_rrc->rrc_container_length; + memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length); + } + itti_send_msg_to_task (TASK_CU_F1, module_id, message_p); +} + +void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) +{ + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; +} diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 3517cf76a0..5d1e3e97d0 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -71,7 +71,7 @@ void rrc_coreset_config(NR_ControlResourceSet_t *coreset, coreset->pdcch_DMRS_ScramblingID = NULL; } -uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc) { +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc) { uint64_t bitmap=0; switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -138,8 +138,7 @@ void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_sl } } - -void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, +void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int uid, int num_dl_antenna_ports, @@ -324,6 +323,130 @@ void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp, csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL; } +// TODO: Implement to b_SRS = 1 and b_SRS = 2 +long rrc_get_max_nr_csrs(const uint8_t max_rbs, const long b_SRS) { + + if(b_SRS>0) { + LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); + return 0; // This c_srs is always valid + } + + const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, + 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, + 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, + 256, 264, 272, 272, 272 }; + + long c_srs = 0; + uint16_t m = 4; + for(int c = 1; c<64; c++) { + if(m_SRS[c]>m && m_SRS[c]present = NR_SetupRelease_SRS_Config_PR_setup; + + NR_SRS_Config_t *srs_Config; + if (setup_release_srs_Config->choice.setup) { + srs_Config = setup_release_srs_Config->choice.setup; + if (srs_Config->srs_ResourceSetToReleaseList) { + free(srs_Config->srs_ResourceSetToReleaseList); + } + if (srs_Config->srs_ResourceSetToAddModList) { + free(srs_Config->srs_ResourceSetToAddModList); + } + if (srs_Config->srs_ResourceToReleaseList) { + free(srs_Config->srs_ResourceToReleaseList); + } + if (srs_Config->srs_ResourceToAddModList) { + free(srs_Config->srs_ResourceToAddModList); + } + free(srs_Config); + } + + setup_release_srs_Config->choice.setup = calloc(1,sizeof(*setup_release_srs_Config->choice.setup)); + srs_Config = setup_release_srs_Config->choice.setup; + + srs_Config->srs_ResourceSetToReleaseList = NULL; + + srs_Config->srs_ResourceSetToAddModList = calloc(1,sizeof(*srs_Config->srs_ResourceSetToAddModList)); + NR_SRS_ResourceSet_t *srs_resset0 = calloc(1,sizeof(*srs_resset0)); + srs_resset0->srs_ResourceSetId = 0; + srs_resset0->srs_ResourceIdList = calloc(1,sizeof(*srs_resset0->srs_ResourceIdList)); + NR_SRS_ResourceId_t *srs_resset0_id = calloc(1,sizeof(*srs_resset0_id)); + *srs_resset0_id = 0; + ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list, srs_resset0_id); + srs_Config->srs_ResourceToReleaseList=NULL; + if (do_srs) { + srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_periodic; + srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic)); + srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL; + } else { + srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_aperiodic; + srs_resset0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic)); + srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger=1; + srs_resset0->resourceType.choice.aperiodic->csi_RS=NULL; + srs_resset0->resourceType.choice.aperiodic->slotOffset = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic->slotOffset)); + *srs_resset0->resourceType.choice.aperiodic->slotOffset = 2; + srs_resset0->resourceType.choice.aperiodic->ext1 = NULL; + } + srs_resset0->usage=NR_SRS_ResourceSet__usage_codebook; + srs_resset0->alpha = calloc(1,sizeof(*srs_resset0->alpha)); + *srs_resset0->alpha = NR_Alpha_alpha1; + srs_resset0->p0 = calloc(1,sizeof(*srs_resset0->p0)); + *srs_resset0->p0 =-80; + srs_resset0->pathlossReferenceRS = NULL; + srs_resset0->srs_PowerControlAdjustmentStates = NULL; + ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceSetToAddModList->list,srs_resset0); + + srs_Config->srs_ResourceToReleaseList = NULL; + + srs_Config->srs_ResourceToAddModList = calloc(1,sizeof(*srs_Config->srs_ResourceToAddModList)); + NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); + srs_res0->srs_ResourceId = 0; + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + srs_res0->ptrs_PortIndex = NULL; + srs_res0->transmissionComb.present = NR_SRS_Resource__transmissionComb_PR_n2; + srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); + srs_res0->transmissionComb.choice.n2->combOffset_n2 = 0; + srs_res0->transmissionComb.choice.n2->cyclicShift_n2 = 0; + srs_res0->resourceMapping.startPosition = 2 + uid%2; + srs_res0->resourceMapping.nrofSymbols = NR_SRS_Resource__resourceMapping__nrofSymbols_n1; + srs_res0->resourceMapping.repetitionFactor = NR_SRS_Resource__resourceMapping__repetitionFactor_n1; + srs_res0->freqDomainPosition = 0; + srs_res0->freqDomainShift = 0; + srs_res0->freqHopping.b_SRS = 0; + srs_res0->freqHopping.b_hop = 0; + srs_res0->freqHopping.c_SRS = servingcellconfigcommon ? + rrc_get_max_nr_csrs( + NRRIV2BW(servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275), + srs_res0->freqHopping.b_SRS) : 0; + srs_res0->groupOrSequenceHopping = NR_SRS_Resource__groupOrSequenceHopping_neither; + if (do_srs) { + srs_res0->resourceType.present = NR_SRS_Resource__resourceType_PR_periodic; + srs_res0->resourceType.choice.periodic = calloc(1,sizeof(*srs_res0->resourceType.choice.periodic)); + srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160; + srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.choice.sl160 = 17 + (uid>1)*10; // 17/17/.../147/157 are mixed slots + } else { + srs_res0->resourceType.present = NR_SRS_Resource__resourceType_PR_aperiodic; + srs_res0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_res0->resourceType.choice.aperiodic)); + } + srs_res0->sequenceId = 40; + srs_res0->spatialRelationInfo = calloc(1,sizeof(*srs_res0->spatialRelationInfo)); + srs_res0->spatialRelationInfo->servingCellId = NULL; + srs_res0->spatialRelationInfo->referenceSignal.present = NR_SRS_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; + srs_res0->spatialRelationInfo->referenceSignal.choice.csi_RS_Index = 0; + ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0); +} void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, NR_ServingCellConfigCommon_t *scc, @@ -331,6 +454,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, int rbsize, int mcs_table) { + NR_Phy_Parameters_t *phy_Parameters = &cap->phy_Parameters; int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; NR_BandNR_t *nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t)); nr_bandnr->bandNR = band; @@ -344,8 +468,8 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, *bandNRinfo->pdsch_256QAM_FR2 = NR_BandNR__pdsch_256QAM_FR2_supported; } else{ - cap->phy_Parameters.phy_ParametersFR1 = CALLOC(1,sizeof(*cap->phy_Parameters.phy_ParametersFR1)); - NR_Phy_ParametersFR1_t *phy_fr1 = cap->phy_Parameters.phy_ParametersFR1; + phy_Parameters->phy_ParametersFR1 = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFR1)); + NR_Phy_ParametersFR1_t *phy_fr1 = phy_Parameters->phy_ParametersFR1; phy_fr1->pdsch_256QAM_FR1 = CALLOC(1,sizeof(*phy_fr1->pdsch_256QAM_FR1)); *phy_fr1->pdsch_256QAM_FR1 = NR_Phy_ParametersFR1__pdsch_256QAM_FR1_supported; } @@ -366,9 +490,12 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, *fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256; ASN_SEQUENCE_ADD(&fs->featureSetsDownlinkPerCC->list, fs_cc); } + + phy_Parameters->phy_ParametersFRX_Diff = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFRX_Diff)); + phy_Parameters->phy_ParametersFRX_Diff->pucch_F0_2WithoutFH = NULL; } -void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc, +void nr_rrc_config_dl_tda(const NR_ServingCellConfigCommon_t *scc, NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList, int curr_bwp) { @@ -421,7 +548,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){ pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long)); *pusch_timedomainresourceallocation->k2 = k2; pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; - pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13); + pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13); ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation); if(frame_type==TDD) { @@ -454,10 +581,210 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){ } } -void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time) { + + pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); + long *delay[8]; + for (int i=0;i<8;i++) { + delay[i] = calloc(1,sizeof(*delay[i])); + *delay[i] = i+min_feedback_time; + ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); + } +} + +// PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213) +void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap) { + + NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset)); + pucchresset->pucch_ResourceSetId = 0; + NR_PUCCH_ResourceId_t *pucchid=calloc(1,sizeof(*pucchid)); + *pucchid=0; + ASN_SEQUENCE_ADD(&pucchresset->resourceList.list,pucchid); + pucchresset->maxPayloadSize=NULL; + + if(uecap) { + long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; + AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F0 without frequency hopping. Current configuration is without FH\n"); + } + + NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); + pucchres0->pucch_ResourceId=*pucchid; + pucchres0->startingPRB= (8 + uid) % curr_bwp; + pucchres0->intraSlotFrequencyHopping=NULL; + pucchres0->secondHopPRB=NULL; + pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; + pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); + pucchres0->format.choice.format0->initialCyclicShift=0; + pucchres0->format.choice.format0->nrofSymbols=1; + pucchres0->format.choice.format0->startingSymbolIndex=13; + ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); + + ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset); +} + + +// PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2) +void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap) { + + NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset)); + pucchresset->pucch_ResourceSetId = 1; + NR_PUCCH_ResourceId_t *pucchressetid=calloc(1,sizeof(*pucchressetid)); + *pucchressetid=2; + ASN_SEQUENCE_ADD(&pucchresset->resourceList.list,pucchressetid); + pucchresset->maxPayloadSize=NULL; + + if(uecap) { + long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; + AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F2 without frequency hopping. Current configuration is without FH\n"); + } + + NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); + pucchres2->pucch_ResourceId=*pucchressetid; + pucchres2->startingPRB=0; + pucchres2->intraSlotFrequencyHopping=NULL; + pucchres2->secondHopPRB=NULL; + pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; + pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); + pucchres2->format.choice.format2->nrofPRBs=8; + pucchres2->format.choice.format2->nrofSymbols=1; + pucchres2->format.choice.format2->startingSymbolIndex=13; + ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); + + ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset); + + pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); + pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; + NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); + pucch_Config->format2->choice.setup = pucchfmt2; + pucchfmt2->interslotFrequencyHopping=NULL; + pucchfmt2->additionalDMRS=NULL; + pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); + *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; + pucchfmt2->nrofSlots=NULL; + pucchfmt2->pi2BPSK=NULL; + + // to check UE capabilities for that in principle + pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); + *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; + +} + +void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs) { + + pucch_Config->pucch_PowerControl = calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); + NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); + p00->p0_PUCCH_Id = 1; + p00->p0_PUCCH_Value = 0; + pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); + ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); + + pucch_Config->pucch_PowerControl->pathlossReferenceRSs = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->pathlossReferenceRSs)); + struct NR_PUCCH_PathlossReferenceRS *PL_ref_RS = calloc(1,sizeof(*PL_ref_RS)); + PL_ref_RS->pucch_PathlossReferenceRS_Id = 0; + if(do_csirs) { + PL_ref_RS->referenceSignal.present = NR_PUCCH_PathlossReferenceRS__referenceSignal_PR_csi_RS_Index; + PL_ref_RS->referenceSignal.choice.csi_RS_Index = 0; + } + else { + PL_ref_RS->referenceSignal.present = NR_PUCCH_PathlossReferenceRS__referenceSignal_PR_ssb_Index; + PL_ref_RS->referenceSignal.choice.ssb_Index = 0; + } + ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->pathlossReferenceRSs->list,PL_ref_RS); + + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); + *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); + *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; + + pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); + pucch_Config->spatialRelationInfoToReleaseList=NULL; + NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); + pucchspatial->pucch_SpatialRelationInfoId = 1; + pucchspatial->servingCellId = NULL; + if(do_csirs) { + pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; + pucchspatial->referenceSignal.choice.csi_RS_Index = 0; + } + else { + pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; + pucchspatial->referenceSignal.choice.ssb_Index = 0; + } + + pucchspatial->pucch_PathlossReferenceRS_Id = PL_ref_RS->pucch_PathlossReferenceRS_Id; + pucchspatial->p0_PUCCH_Id = p00->p0_PUCCH_Id; + pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; + ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); +} + +static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig, + const NR_ServingCellConfigCommon_t *scc) +{ + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + int sr_slot = 1; // in FDD SR in slot 1 + if(tdd) + sr_slot = tdd->nrofDownlinkSlots; // SR in the first uplink slot + + schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); + + if(sr_slot<10){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = sr_slot; + return; + } + if(sr_slot<20){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl20 = sr_slot; + return; + } + if(sr_slot<40){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = sr_slot; + return; + } + if(sr_slot<80){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl80 = sr_slot; + return; + } + if(sr_slot<160){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl160 = sr_slot; + return; + } + if(sr_slot<320){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl320 = sr_slot; + return; + } + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl640 = sr_slot; +} + +void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config) { + + // format with <=2 bits in pucch resource set 0 + NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; + // assigning the 1st pucch resource in the set to scheduling request + NR_PUCCH_ResourceId_t *pucchressetid = pucchresset->resourceList.list.array[0]; + + pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); + NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); + schedulingRequestResourceConfig->schedulingRequestResourceId = 1; + schedulingRequestResourceConfig->schedulingRequestID = 0; + + set_SR_periodandoffset(schedulingRequestResourceConfig, scc); + + schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); + *schedulingRequestResourceConfig->resource = *pucchressetid; + ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); +} + +void set_dl_mcs_table(int scs, + NR_UE_NR_Capability_t *cap, NR_SpCellConfig_t *SpCellConfig, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, - NR_ServingCellConfigCommon_t *scc) { + const NR_ServingCellConfigCommon_t *scc) { if (cap == NULL){ bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NULL; @@ -494,7 +821,7 @@ void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, if(bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table)); *bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256; -// set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list + // set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list AssertFatal(SpCellConfig!=NULL,"SpCellConfig shouldn't be null\n"); AssertFatal(SpCellConfig->spCellConfigDedicated!=NULL,"SpCellConfigDedicated shouldn't be null\n"); if (SpCellConfig->spCellConfigDedicated->csi_MeasConfig && diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 8b28e2d584..27aebcf94b 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -111,16 +111,22 @@ typedef struct physicalcellgroup_s{ long RNTI_Value[MAX_NUM_CCs]; }physicalcellgroup_t; -uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc); +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc); void rrc_coreset_config(NR_ControlResourceSet_t *coreset, int bwp_id, int curr_bwp, uint64_t ssb_bitmap); -void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc, +void nr_rrc_config_dl_tda(const NR_ServingCellConfigCommon_t *scc, NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList, int curr_bwp); void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay); -void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, +void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap); +void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap); +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time); +void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs); +void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config); +void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int uid, int num_dl_antenna_ports, @@ -128,15 +134,19 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, int do_csirs); void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp, NR_CSI_MeasConfig_t *csi_MeasConfig); -void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, +void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, + const NR_ServingCellConfigCommon_t *servingcellconfigcommon, + const int uid, + const int do_srs); +void set_dl_mcs_table(int scs, + NR_UE_NR_Capability_t *cap, NR_SpCellConfig_t *SpCellConfig, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, - NR_ServingCellConfigCommon_t *scc); + const NR_ServingCellConfigCommon_t *scc); void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, NR_ServingCellConfigCommon_t *scc, int numerology, int rbsize, int mcs_table); - #endif diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 89ae9c1d2b..e9d9766f41 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -36,12 +36,13 @@ #include #include "collection/tree.h" +#include "collection/linear_alloc.h" #include "nr_rrc_types.h" +#include "common/ngran_types.h" #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" -#include "RRC/LTE/rrc_defs.h" -//#include "LAYER2/RLC/rlc.h" +#include "mac_rrc_dl.h" //#include "COMMON/mac_rrc_primitives.h" @@ -79,17 +80,6 @@ #include "commonDef.h" - -/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ - -typedef unsigned int uid_nr_t; -#define NR_UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((MAX_MOBILES_PER_GNB/8)/sizeof(unsigned int)) + 1) - -typedef struct nr_uid_linear_allocator_s { - unsigned int bitmap[NR_UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; -} nr_uid_allocator_t; - - #define PROTOCOL_NR_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT #define PROTOCOL_NR_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) @@ -173,7 +163,7 @@ typedef struct UE_RRC_INFO_NR_s { } __attribute__ ((__packed__)) NR_UE_RRC_INFO; typedef struct UE_S_TMSI_NR_s { - boolean_t presence; + bool presence; uint16_t amf_set_id; uint8_t amf_pointer; uint32_t fiveg_tmsi; @@ -282,12 +272,11 @@ typedef struct pdu_session_param_s { typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; - LTE_SCellToAddMod_r10_t sCell_config[2]; NR_SRB_ToAddModList_t *SRB_configList; - NR_SRB_ToAddModList_t *SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_SRB_ToAddModList_t *SRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; NR_DRB_ToAddModList_t *DRB_configList; - NR_DRB_ToAddModList_t *DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint8_t DRB_active[8]; NR_SRB_INFO SI; @@ -295,7 +284,7 @@ typedef struct gNB_RRC_UE_s { NR_SRB_INFO_TABLE_ENTRY Srb1; NR_SRB_INFO_TABLE_ENTRY Srb2; NR_MeasConfig_t *measConfig; - HANDOVER_INFO *handover_info; + NR_HANDOVER_INFO *handover_info; NR_MeasResults_t *measResults; @@ -352,7 +341,7 @@ typedef struct gNB_RRC_UE_s { /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_e_rabs; uint8_t nb_of_failed_e_rabs; - e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + nr_e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* Total number of pdu session already setup in the list */ uint8_t setup_pdu_sessions; /* Number of pdu session to be setup in the list */ @@ -363,7 +352,7 @@ typedef struct gNB_RRC_UE_s { pdu_session_param_t modify_pdusession[NR_NB_RB_MAX]; /* list of e_rab to be setup by RRC layers */ /* list of pdu session to be setup by RRC layers */ - e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; pdu_session_param_t pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION]; //release e_rabs uint8_t nb_release_of_e_rabs; @@ -410,8 +399,6 @@ typedef struct gNB_RRC_UE_s { } gNB_RRC_UE_t; -typedef uid_t ue_uid_t; - typedef struct rrc_gNB_ue_context_s { /* Tree related data */ RB_ENTRY(rrc_gNB_ue_context_s) entries; @@ -422,7 +409,7 @@ typedef struct rrc_gNB_ue_context_s { rnti_t ue_id_rnti; // another key for protocol layers but should not be used as a key for RB tree - ue_uid_t local_uid; + uid_t local_uid; /* UE id for initial connection to S1AP */ struct gNB_RRC_UE_s ue_context; @@ -435,7 +422,7 @@ typedef struct { uint8_t sizeof_MIB; uint8_t *SIB1; - uint8_t sizeof_SIB1; + uint16_t sizeof_SIB1; uint8_t *SIB23; uint8_t sizeof_SIB23; @@ -447,7 +434,8 @@ typedef struct { NR_BCCH_BCH_Message_t mib; NR_BCCH_BCH_Message_t *mib_DU; - NR_BCCH_DL_SCH_Message_t *siblock1_DU; + NR_SIB1_t *siblock1_DU; + //NR_BCCH_DL_SCH_Message_t *siblock1_DU; NR_SIB1_t *sib1; NR_SIB2_t *sib2; NR_SIB3_t *sib3; @@ -479,6 +467,11 @@ typedef struct { int do_drb_integrity; } nr_security_configuration_t; +typedef struct nr_mac_rrc_dl_if_s { + /* TODO add other message types as necessary */ + dl_rrc_message_transfer_func_t dl_rrc_message_transfer; +} nr_mac_rrc_dl_if_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -488,7 +481,7 @@ typedef struct gNB_RRC_INST_s { int module_id; eth_params_t eth_params_s; rrc_gNB_carrier_data_t carrier; - nr_uid_allocator_t uid_allocator; // for rrc_ue_head + uid_allocator_t uid_allocator; RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti int Nb_ue; hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t @@ -528,6 +521,8 @@ typedef struct gNB_RRC_INST_s { // security configuration (preferred algorithms) nr_security_configuration_t security; + + nr_mac_rrc_dl_if_t mac_rrc; } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 6a320123de..b90cf4dfa4 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -108,9 +108,9 @@ void rrc_gNB_generate_RRCSetup( const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id); + const uint8_t *masterCellGroup, + int masterCellGroup_len, + NR_ServingCellConfigCommon_t *scc); int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); @@ -120,7 +120,7 @@ rrc_gNB_generate_SecurityModeCommand( rrc_gNB_ue_context_t *const ue_context_pP ); -uint8_t + uint8_t rrc_gNB_get_next_transaction_identifier( module_id_t gnb_mod_idP ); @@ -174,19 +174,6 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, const int dl_bwp_id, const int ul_bwp_id); -int8_t nr_mac_rrc_data_ind( - const module_id_t module_idP, - const int CC_id, - const frame_t frameP, - const sub_frame_t sub_frameP, - const int UE_id, - const rnti_t rntiP, - const rb_id_t srb_idP, - const uint8_t *sduP, - const sdu_size_t sdu_lenP, - const boolean_t brOption -); - int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP, protocol_ctxt_t *const ctxt_pP, const int dl_bwp_id, @@ -195,8 +182,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, const uint8_t *buffer, int buffer_length, - OCTET_STRING_t *du_to_cu_rrc_container, - const int CC_id); + const uint8_t *du_to_cu_rrc_container, + int du_to_cu_rrc_container_length); void rrc_gNB_generate_dedicatedRRCReconfiguration_release( @@ -209,7 +196,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( void rrc_gNB_generate_dedicatedRRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP); + rrc_gNB_ue_context_t *ue_context_pP, + NR_CellGroupConfig_t *cell_groupConfig_from_DU); rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const NR_SRB_ToAddModList_t * const srb2add_listP, @@ -218,16 +206,15 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); -boolean_t nr_rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - NR_SRB_ToAddModList_t *const srb2add_list, - NR_DRB_ToAddModList_t *const drb2add_list, - NR_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - uint8_t *const kUPint - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); +bool nr_rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + uint8_t *const kUPint, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d03e00f8c6..8be829f51f 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -99,6 +99,7 @@ #include #include #include +#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "BIT_STRING.h" #include "assertions.h" @@ -115,16 +116,16 @@ uint8_t first_rrcreconfiguration = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -boolean_t DURecvCb( protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); @@ -164,9 +165,8 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration LOG_I(NR_RRC,"Done init_NR_SI\n"); - if (NODE_IS_MONOLITHIC(rrc->node_type)){ + if (NODE_IS_MONOLITHIC(rrc->node_type) || NODE_IS_DU(rrc->node_type)){ rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -196,21 +196,41 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration } } +static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc) +{ + switch (rrc->node_type) { + case ngran_gNB_CU: + mac_rrc_dl_f1ap_init(&rrc->mac_rrc); + break; + case ngran_gNB_DU: + /* silently drop this, as we currently still need the RRC at the DU. As + * soon as this is not the case anymore, we can add the AssertFatal() */ + //AssertFatal(1==0,"nothing to do for DU\n"); + break; + case ngran_gNB: + mac_rrc_dl_direct_init(&rrc->mac_rrc); + break; + default: + AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type); + break; + } +} + char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) { - protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt = { 0 }; gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gnb_mod_idP, GNB_FLAG_YES, NOT_A_RNTI, 0, 0,gnb_mod_idP); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Init...\n", PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); - AssertFatal(rrc != NULL, "RC.nrrrc not initialized!"); AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); AssertFatal(configuration!=NULL,"configuration input is null\n"); rrc->module_id = gnb_mod_idP; rrc->Nb_ue = 0; rrc->carrier.Srb0.Active = 0; - nr_uid_linear_allocator_init(&rrc->uid_allocator); + rrc_gNB_mac_rrc_init(rrc); + uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); rrc->s1ap_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); @@ -276,7 +296,6 @@ void apply_macrlc_config(gNB_RRC_INST *rrc, NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL; rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -320,119 +339,52 @@ void rrc_gNB_generate_RRCSetup( const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id -) + const uint8_t *masterCellGroup, + int masterCellGroup_len, + NR_ServingCellConfigCommon_t *scc) //----------------------------------------------------------------------------- { - LOG_D(NR_RRC, "rrc_gNB_generate_RRCSetup \n"); - MessageDef *message_p; + LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04x\n", ctxt_pP->rnti); // T(T_GNB_RRC_SETUP, // T_INT(ctxt_pP->module_id), // T_INT(ctxt_pP->frame), // T_INT(ctxt_pP->subframe), // T_INT(ctxt_pP->rnti)); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - NR_ServingCellConfig_t *servingcellconfigdedicated = rrc->configuration.scd; - int16_t ret = do_RRCSetup(ue_context_pP, - (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - masterCellGroup_from_DU, - scc,servingcellconfigdedicated,&rrc->configuration); - - AssertFatal(ret>0,"Error generating RRCSetup for RRCSetupRequest\n"); - - ue_p->Srb0.Tx_buffer.payload_size = ret; + const NR_ServingCellConfig_t *sccd = rrc->configuration.scd; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + masterCellGroup, + masterCellGroup_len, + scc, + sccd, + &rrc->configuration); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(ue_p->Srb0.Tx_buffer.Payload), ue_p->Srb0.Tx_buffer.payload_size, "[MSG] RRC Setup\n"); - switch (rrc->node_type) { - case ngran_gNB_CU: - // create an ITTI message - /* TODO: F1 IDs ar missing in RRC */ - nr_rrc_pdcp_config_asn1_req(ctxt_pP, - ue_context_pP->ue_context.SRB_configList, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); - F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload; - F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; - F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; - F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0; - F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown - F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti; - F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH; - F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1; - F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0; - itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); - LOG_D(NR_RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; - break; + /* TODO: this should go through the E1 interface */ + apply_pdcp_config(ue_context_pP,ctxt_pP); - case ngran_gNB_DU: - // nothing to do for DU - AssertFatal(1==0,"nothing to do for DU\n"); - break; - - case ngran_gNB: - { - // rrc_mac_config_req_gNB - -#ifdef ITTI_SIM - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; - /* init timers */ - // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; - - // configure MAC - - apply_macrlc_config(rrc,ue_context_pP,ctxt_pP); - - apply_pdcp_config(ue_context_pP,ctxt_pP); -#endif - } - break; - - default: - LOG_W(NR_RRC, "Unknown node type %d\n", rrc->node_type); - break; - } + f1ap_dl_rrc_message_t dl_rrc = { + .old_gNB_DU_ue_id = 0xFFFFFF, + .rrc_container = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload, + .rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size, + .rnti = ue_p->rnti, + .srb_id = CCCH + }; + rrc->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); } //----------------------------------------------------------------------------- @@ -446,8 +398,8 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); rrc_gNB_ue_context_t *ue_context_pP = NULL; gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id]; - NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon; - NR_ServingCellConfig_t *servingcellconfigdedicated = rrc_instance_p->configuration.scd; + const NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon; + const NR_ServingCellConfig_t *sccd = rrc_instance_p->configuration.scd; ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0); @@ -456,7 +408,10 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), NULL, - scc,servingcellconfigdedicated,&rrc_instance_p->configuration); + 0, + scc, + sccd, + &rrc_instance_p->configuration); AssertFatal(ret>0,"Error generating RRCSetup for RRCReestablishmentRequest\n"); @@ -472,7 +427,6 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_mac_config_req_gNB(rrc_instance_p->module_id, - rrc_instance_p->configuration.ssb_SubcarrierOffset, rrc_instance_p->configuration.pdsch_AntennaPorts, rrc_instance_p->configuration.pusch_AntennaPorts, rrc_instance_p->configuration.sib1_tda, @@ -494,25 +448,12 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( ue_context_pP->ue_context.ue_release_timer_thres = 1000; /* init timers */ // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif } void rrc_gNB_generate_RRCReject( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - const int CC_id -) + rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); @@ -554,16 +495,8 @@ rrc_gNB_generate_RRCReject( case ngran_gNB: { -#ifdef ITTI_SIM - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif + // NOTE: there was ITTI_SIM which has been removed. This case is maybe + // not necessary anymore // rrc_mac_config_req_gNB } break; @@ -771,17 +704,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( case ngran_gNB: { -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, @@ -798,7 +720,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( buffer, PDCP_TRANSMISSION_MODE_CONTROL); // rrc_pdcp_config_asn1_req -#endif // rrc_rlc_config_asn1_req } break; @@ -808,8 +729,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( } if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -838,7 +759,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( void rrc_gNB_generate_dedicatedRRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP + rrc_gNB_ue_context_t *ue_context_pP, + NR_CellGroupConfig_t *cell_groupConfig_from_DU ) //----------------------------------------------------------------------------- { @@ -861,7 +783,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( uint8_t drb_id_to_setup_start = 1; uint8_t nb_drb_to_setup = 0; long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) - NR_CellGroupConfig_t *cellGroupConfig; + NR_CellGroupConfig_t *cellGroupConfig = NULL; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); @@ -918,7 +840,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; } - sdap_config->defaultDRB = TRUE; + sdap_config->defaultDRB = true; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); @@ -1017,9 +939,17 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( } memset(buffer, 0, sizeof(buffer)); - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + if(cell_groupConfig_from_DU == NULL){ + cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or + // bearer IDs for the DRBs + fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + } + else{ + LOG_I(NR_RRC, "Master cell group originating from the DU \n"); + cellGroupConfig = cell_groupConfig_from_DU; + } - fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, *SRB_configList2, @@ -1052,17 +982,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1071,11 +990,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -1251,17 +1168,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1270,7 +1176,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && @@ -1364,17 +1269,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1383,7 +1277,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && @@ -1420,7 +1313,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; ue_context_pP->ue_context.ue_reestablishment_timer = 0; @@ -1442,7 +1334,6 @@ rrc_gNB_process_RRCReconfigurationComplete( &kRRCint); /* Refresh SRBs/DRBs */ -#ifndef ITTI_SIM LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); nr_rrc_pdcp_config_asn1_req(ctxt_pP, @@ -1459,7 +1350,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NULL, get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); /* Refresh SRBs/DRBs */ - if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -1469,50 +1359,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NULL, get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); } - else if(SRB_configList!=NULL || DRB_configList!=NULL){ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); - req->gNB_CU_ue_id = 0; - req->gNB_DU_ue_id = 0; - req->rnti = ue_context_pP->ue_context.rnti; - req->mcc = rrc->configuration.mcc[0]; - req->mnc = rrc->configuration.mnc[0]; - req->mnc_digit_length = rrc->configuration.mnc_digit_length[0]; - req->nr_cellid = rrc->nr_cellid; - if(SRB_configList!=NULL){ - req->srbs_to_be_setup = malloc(SRB_configList->list.count*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = SRB_configList->list.count; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - for (int i = 0; i < SRB_configList->list.count; i++){ - if(SRB_configList->list.array[i]->srb_Identity > 1){ - SRBs[i].srb_id = SRB_configList->list.array[i]->srb_Identity; - SRBs[i].lcid = SRB_configList->list.array[i]->srb_Identity; - } - } - } - if(DRB_configList!=NULL){ - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - req->drbs_to_be_setup = malloc(DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); - req->drbs_to_be_setup_length = DRB_configList->list.count; - f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; - LOG_I(RRC, "Length of DRB list:%d, %d \n", DRB_configList->list.count, req->drbs_to_be_setup_length); - for (int i = 0; i < DRB_configList->list.count; i++){ - DRBs[i].drb_id = DRB_configList->list.array[i]->drb_Identity; - DRBs[i].rlc_mode = RLC_MODE_AM; - DRBs[i].up_ul_tnl[0].tl_address = inet_addr(rrc->eth_params_s.my_addr); - DRBs[i].up_ul_tnl[0].port=rrc->eth_params_s.my_portd; - DRBs[i].up_ul_tnl_length = 1; - DRBs[i].up_dl_tnl[0].tl_address = inet_addr(rrc->eth_params_s.remote_addr); - DRBs[i].up_dl_tnl[0].port=rrc->eth_params_s.remote_portd; - DRBs[i].up_dl_tnl_length = 1; - } - LOG_I(RRC, "Send F1AP_UE_CONTEXT_SETUP_REQ with ITTI\n"); - } - itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); - } -#endif /* Set the SRB active in UE context */ if (SRB_configList != NULL) { @@ -1674,18 +1520,6 @@ rrc_gNB_generate_RRCReestablishment( rnti); } #endif -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, ue_context->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, ue_context->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = ue_context->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif - } //----------------------------------------------------------------------------- @@ -1806,15 +1640,16 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( } } - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; /* Save e RAB information for later */ - memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); for ( j = 0, i = 0; i < NB_RB_MAX; i++) { if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) { create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; create_tunnel_req.incoming_rb_id[j] = i+1; create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; + // to be developped, use the first QFI only + create_tunnel_req.outgoing_qfi[j] = ue_context_pP->ue_context.pduSession[i].param.qos[0].qfi; memcpy(create_tunnel_req.dst_addr[j].buffer, ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer, sizeof(uint8_t)*20); @@ -1865,7 +1700,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.rnti = ctxt_pP->rnti; if (AMF_MODE_ENABLED) { - uint8_t send_security_mode_command = FALSE; + uint8_t send_security_mode_command = false; nr_rrc_pdcp_config_security( ctxt_pP, ue_context_pP, @@ -1922,17 +1757,6 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1941,7 +1765,6 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { @@ -1988,7 +1811,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP NULL, NULL, NULL, - NULL, + ue_context_pP, NULL, NULL, NULL, @@ -1996,7 +1819,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP gNB_RrcConfigurationReq *configuration = &RC.nrrrc[ctxt_pP->module_id]->configuration; rrc_mac_config_req_gNB(ctxt_pP->module_id, - configuration->ssb_SubcarrierOffset, configuration->pdsch_AntennaPorts, configuration->pusch_AntennaPorts, configuration->sib1_tda, @@ -2036,8 +1858,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, const uint8_t *buffer, int buffer_length, - OCTET_STRING_t *du_to_cu_rrc_container, - const int CC_id) + const uint8_t *du_to_cu_rrc_container, + int du_to_cu_rrc_container_len) { module_id_t Idx; asn_dec_rval_t dec_rval; @@ -2047,22 +1869,16 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; uint64_t random_value = 0; - int i; - dec_rval = uper_decode( NULL, - &asn_DEF_NR_UL_CCCH_Message, - (void **)&ul_ccch_msg, - (uint8_t *) buffer, - 100, - 0, - 0); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, inst %ld, payload_size %d\n", ctxt_pP->rnti, ctxt_pP->instance, buffer_length); + dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0); - if (dec_rval.consumed == 0) { - /* TODO */ - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - return -1; - } + if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return -1; + } if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { switch (ul_ccch_msg->message.choice.c1->present) { @@ -2153,7 +1969,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, } if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = true; ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; } } @@ -2168,8 +1984,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_gNB_generate_RRCReject(ctxt_pP, - rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), - CC_id); + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti)); break; } @@ -2178,8 +1993,8 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, rrc_gNB_generate_RRCSetup(ctxt_pP, rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), du_to_cu_rrc_container, - gnb_rrc_inst->carrier.servingcellconfigcommon, - CC_id); + du_to_cu_rrc_container_len, + gnb_rrc_inst->carrier.servingcellconfigcommon); } break; @@ -2211,13 +2026,13 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), rrcReestablishmentRequest.ue_Identity.physCellId, RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } LOG_D(NR_RRC, "physCellId is %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId); - for (i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { + for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); } @@ -2228,7 +2043,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } @@ -2240,7 +2055,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } #if(0) @@ -2251,14 +2066,14 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } //previous rnti rnti_t previous_rnti = 0; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][1] == c_rnti) { previous_rnti = reestablish_rnti_map[i][0]; break; @@ -2272,7 +2087,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } } @@ -2326,7 +2141,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, ue_context_p->ue_context.reestablishment_xid = -1; // insert C-RNTI to map - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][0] == 0) { reestablish_rnti_map[i][0] = ctxt_pP->rnti; reestablish_rnti_map[i][1] = c_rnti; @@ -2342,7 +2157,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, rrcReestablishmentRequest.ue_Identity.physCellId, ue_context_p->ue_context.reestablishment_cause); - ue_context_p->ue_context.primaryCC_id = CC_id; + ue_context_p->ue_context.primaryCC_id = 0; //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; Idx = DCCH; // SRB1 @@ -2364,7 +2179,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, CC_id); + rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, 0); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -2630,7 +2445,7 @@ rrc_gNB_decode_dcch( fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, (uint32_t)fiveg_s_TMSI); - if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == true) { ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; @@ -2814,11 +2629,74 @@ rrc_gNB_decode_dcch( ul_dcch_msg); } - if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { - rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p); - } else { - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)){ + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL); + } else { + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + } } + else{ + /*Generate a UE context setup request message towards the DU to provide the UE + *capability info and get the updates on master cell group config from the DU*/ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); + f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); + //UE_IDs will be extracted from F1AP layer + req->gNB_CU_ue_id = 0; + req->gNB_DU_ue_id = 0; + req->rnti = ue_context_p->ue_context.rnti; + req->mcc = RC.nrrrc[ctxt_pP->module_id]->configuration.mcc[0]; + req->mnc = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc[0]; + req->mnc_digit_length = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc_digit_length[0]; + req->nr_cellid = RC.nrrrc[ctxt_pP->module_id]->nr_cellid; + + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + /*Instruction towards the DU for SRB2 configuration*/ + req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); + req->srbs_to_be_setup_length = 1; + f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; + SRBs[0].srb_id = 2; + SRBs[0].lcid = 2; + + /*Instruction towards the DU for DRB configuration and tunnel creation*/ + req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); + req->drbs_to_be_setup_length = 1; + f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; + LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); + DRBs[0].drb_id = 1; + DRBs[0].rlc_mode = RLC_MODE_AM; + DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_addr); + DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_portd; + DRBs[0].up_ul_tnl_length = 1; + DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_addr); + DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_portd; + DRBs[0].up_dl_tnl_length = 1; + } + if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == + NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { + struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + if(ue_CapabilityRAT_ContainerList!=NULL){ + LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is present \n"); + req->cu_to_du_rrc_information = calloc(1,sizeof(cu_to_du_rrc_information_t)); + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = calloc(1,4096); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, + NULL, + ue_CapabilityRAT_ContainerList, + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + 4096); + AssertFatal (enc_rval.encoded > 0, "ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = (enc_rval.encoded+7)>>3; + } + else{ + LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is not present \n"); + } + } + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); + } + break; @@ -2931,11 +2809,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { memset(mib->message.choice.mib,0,sizeof(struct NR_MIB)); memcpy(mib->message.choice.mib, mib_DU->message.choice.mib, sizeof(struct NR_MIB)); - rrc->carrier.SIB1 = malloc(f1_setup_req->sib1_length[i]); - rrc->carrier.sizeof_SIB1 = f1_setup_req->sib1_length[i]; - memcpy((void *)rrc->carrier.SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); dec_rval = uper_decode_complete(NULL, - &asn_DEF_NR_BCCH_DL_SCH_Message, + &asn_DEF_NR_SIB1, //&asn_DEF_NR_BCCH_DL_SCH_Message, (void **)&rrc->carrier.siblock1_DU, f1_setup_req->sib1[i], f1_setup_req->sib1_length[i]); @@ -2945,12 +2820,12 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { dec_rval.consumed ); // Parse message and extract SystemInformationBlockType1 field - NR_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier.siblock1_DU; - AssertFatal(bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1, - "bcch_message->message.present != NR_BCCH_DL_SCH_MessageType_PR_c1\n"); - AssertFatal(bcch_message->message.choice.c1->present == NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1, - "bcch_message->message.choice.c1->present != NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n"); - rrc->carrier.sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + rrc->carrier.sib1 = rrc->carrier.siblock1_DU; + if ( LOG_DEBUGFLAG(DEBUG_ASN1)){ + LOG_I(NR_RRC, "Printing received SIB1 container inside F1 setup request message:\n"); + xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)rrc->carrier.sib1); + } + rrc->carrier.physCellId = f1_setup_req->cell[i].nr_pci; F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).gNB_CU_name = rrc->node_name; @@ -2994,6 +2869,38 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { }//for (int i=0;inum_cells_available;i++) } +void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + // first get RRC instance (note, no the ITTI instance) + module_id_t i = 0; + for (i=0; i < RC.nb_nr_inst; i++) { + gNB_RRC_INST *rrc = RC.nrrrc[i]; + if (rrc->nr_cellid == ul_rrc->nr_cellid) + break; + } + //AssertFatal(i != RC.nb_nr_inst, "Cell_id not found\n"); + // TODO REMOVE_DU_RRC in monolithic mode, the MAC does not have the + // nr_cellid. Thus, the above check would fail. For the time being, just put + // a warning, as we handle one DU only anyway + if (i == RC.nb_nr_inst) { + i = 0; + LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); + } + protocol_ctxt_t ctxt = { 0 }; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, i, GNB_FLAG_YES, ul_rrc->crnti, 0, 0); + + nr_rrc_gNB_decode_ccch(&ctxt, + ul_rrc->rrc_container, + ul_rrc->rrc_container_length, + ul_rrc->du2cu_rrc_container, + ul_rrc->du2cu_rrc_container_length); + + if (ul_rrc->rrc_container) + free(ul_rrc->rrc_container); + if (ul_rrc->du2cu_rrc_container) + free(ul_rrc->du2cu_rrc_container); +} + void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) { gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; @@ -3008,77 +2915,19 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_t instance) { NRDuDlReq_t * req=&NRDuDlReq(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = req->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); if (req->srb_id == 0) { - NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; - asn_dec_rval_t dec_rval; - dec_rval = uper_decode(NULL, - &asn_DEF_NR_DL_CCCH_Message, - (void **)&dl_ccch_msg, - req->buf->data, - req->buf->size,0,0); - AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n"); - - switch (dl_ccch_msg->message.choice.c1->present) { - case NR_DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(F1AP,"Received PR_NOTHING on DL-CCCH-Message\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(F1AP,"Logical Channel DL-CCCH (SRB0), Received RRCReject\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: { - LOG_I(F1AP, "Logical Channel DL-CCCH (SRB0), Received RRCSetup RNTI %x\n", - req->rnti); - // Get configuration - NR_RRCSetup_t *rrcSetup = dl_ccch_msg->message.choice.c1->choice.rrcSetup; - AssertFatal(rrcSetup!=NULL, "rrcSetup is null\n"); - NR_RRCSetup_IEs_t *rrcSetup_ies = rrcSetup->criticalExtensions.choice.rrcSetup; - ue_context_p->ue_context.SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList; - AssertFatal(rrcSetup_ies->masterCellGroup.buf!=NULL,"masterCellGroup is null\n"); - asn_dec_rval_t dec_rval; - dec_rval = uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&ue_context_p->ue_context.masterCellGroup, - rrcSetup_ies->masterCellGroup.buf, - rrcSetup_ies->masterCellGroup.size,0,0); - AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n"); - apply_macrlc_config(rrc,ue_context_p,&ctxt); - gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); - memcpy((void *)ue_p->Srb0.Tx_buffer.Payload, - (void *)req->buf->data, - req->buf->size); // ie->value.choice.RRCContainer.size - ue_p->Srb0.Tx_buffer.payload_size = req->buf->size; - break; - } // case - - case NR_DL_CCCH_MessageType__c1_PR_spare2: - LOG_I(F1AP, - "Logical Channel DL-CCCH (SRB0), Received spare2\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_spare1: - LOG_I(F1AP, - "Logical Channel DL-CCCH (SRB0), Received spare1\n"); - break; - - default: - AssertFatal(1==0, - "Unknown message\n"); - break; - }// switch case - - return(0); + AssertFatal(0 == 1, "should pass through dl_rrc_message()\n"); } else if (req->srb_id == 1) { NR_DL_DCCH_Message_t *dl_dcch_msg=NULL; asn_dec_rval_t dec_rval; @@ -3213,7 +3062,6 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", req->srb_id); // rlc_op_status_t rlc_status; - // boolean_t ret = TRUE; //LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size); //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) @@ -3238,23 +3086,23 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ // switch (rlc_status) { // case RLC_OP_STATUS_OK: // //LOG_I(F1AP, "Data sending request over RLC succeeded!\n"); - // ret=TRUE; + // ret=true; // break; // case RLC_OP_STATUS_BAD_PARAMETER: // LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - // ret= FALSE; + // ret= false; // break; // case RLC_OP_STATUS_INTERNAL_ERROR: // LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - // ret= FALSE; + // ret= false; // break; // case RLC_OP_STATUS_OUT_OF_RESSOURCES: // LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - // ret= FALSE; + // ret= false; // break; // default: // LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - // ret= FALSE; + // ret= false; // break; // } // switch case // return ret; @@ -3264,11 +3112,13 @@ return 0; static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_SETUP_REQ(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = req->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = @@ -3278,6 +3128,94 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p); uint32_t incoming_teid = 0; + if(req->cu_to_du_rrc_information!=NULL){ + if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + LOG_I(NR_RRC, "Length of ue_CapabilityRAT_ContainerList is: %d \n", (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_UE_CapabilityRAT_ContainerList, + (void **)&ue_CapabilityRAT_ContainerList, + (uint8_t *)req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"UE Capability RAT ContainerList decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_UE_CapabilityRAT_ContainerList, ue_CapabilityRAT_ContainerList, 1 ); + return; + } + //To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ... + int NR_index = -1; + for(int i = 0;i < ue_CapabilityRAT_ContainerList->list.count; i++){ + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_nr){ + LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); + if(ue_context_p->ue_context.UE_Capability_nr){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_nr, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + ue_context_p->ue_context.UE_Capability_size = + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + if(NR_index != -1){ + LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); + exit(1); + } + NR_index = i; + } + + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra_nr){ + LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); + if(ue_context_p->ue_context.UE_Capability_MRDC){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_MRDC, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + ue_context_p->ue_context.UE_MRDC_Capability_size = + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + } + + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra){ + //TODO + } + } + } + } + uint8_t drb_id_to_setup_start = 0; uint8_t nb_drb_to_setup = 0; long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) @@ -3320,22 +3258,38 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; extern instance_t DUuniqInstance; if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; - incoming_teid=newGtpuCreateTunnel(DUuniqInstance, - req->rnti, - drb_p.drb_id, - drb_p.drb_id, - drb_p.up_ul_tnl[0].teid, - addr, - drb_p.up_ul_tnl[0].port, - DURecvCb); + incoming_teid = newGtpuCreateTunnel(DUuniqInstance, + req->rnti, + drb_p.drb_id, + drb_p.drb_id, + drb_p.up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p.up_ul_tnl[0].port, + DURecvCb, + NULL); } } - NR_CellGroupConfig_t *cellGroupConfig; - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0) + // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or + // bearer IDs for the DRBs + fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); apply_macrlc_config(rrc, ue_context_p, &ctxt); + + if(req->rrc_container_length > 0){ + mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__); + memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length); + du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p); + LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n"); + for (int j=0; jrrc_container_length; j++){ + printf("%02x ", pdcp_pdu_p->data[j]); + } + printf("\n"); + } + /* Fill the UE context setup response ITTI message to send to F1AP */ resp->gNB_CU_ue_id = req->gNB_CU_ue_id; resp->rnti = ctxt.rnti; @@ -3370,25 +3324,188 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha else{ LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n"); } - resp->du_to_cu_rrc_information = calloc(1,1024*sizeof(uint8_t)); + /* fixme: + * Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities + */ + resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); + resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, - (void *)cellGroupConfig, - resp->du_to_cu_rrc_information, + ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, 1024); - resp->du_to_cu_rrc_information_length = (enc_rval.encoded+7)>>3; + if (enc_rval.encoded == -1) { + LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name); + exit(-1); + } + resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; free(cellGroupConfig); itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); } +static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ + + f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = + rrc_gNB_get_ue_context(rrc, ctxt.rnti); + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); + uint32_t incoming_teid = 0; + NR_CellGroupConfig_t *cellGroupConfig = NULL; + + /* Configure SRB2 */ + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_SRB_ToAddModList_t *SRB_configList = NULL; + uint8_t SRBs_before_new_addition = 0; + + if(req->srbs_to_be_setup_length>0){ + if(ue_context_p->ue_context.SRB_configList == NULL){ + LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); + ue_context_p->ue_context.SRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.SRB_configList)); + } + SRB_configList = ue_context_p->ue_context.SRB_configList; + SRBs_before_new_addition = SRB_configList->list.count; + for (int i=0; isrbs_to_be_setup_length; i++){ + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id; + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + } + } + + /* Configure DRB */ + NR_DRB_ToAddMod_t *DRB_config = NULL; + NR_DRB_ToAddModList_t *DRB_configList = NULL; + if(req->drbs_to_be_setup_length>0){ + if(ue_context_p->ue_context.DRB_configList == NULL){ + ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); + } + DRB_configList = ue_context_p->ue_context.DRB_configList; + for (int i=0; idrbs_to_be_setup_length; i++){ + DRB_config = CALLOC(1, sizeof(*DRB_config)); + DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; + ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config); + f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; + transport_layer_addr_t addr; + memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); + addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; + extern instance_t DUuniqInstance; + incoming_teid = newGtpuCreateTunnel(DUuniqInstance, + req->rnti, + drb_p.drb_id, + drb_p.drb_id, + drb_p.up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p.up_ul_tnl[0].port, + DURecvCb, + NULL); + } + } + + if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ + cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + uint8_t drb_id_to_setup_start = 1; + long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) + fill_mastercellGroupConfig(cellGroupConfig, + ue_context_p->ue_context.masterCellGroup, + rrc->um_on_default_drb, + drb_id_to_setup_start < 2 ? 1 : 0, + drb_id_to_setup_start, + req->drbs_to_be_setup_length, + drb_priority); + apply_macrlc_config(rrc, ue_context_p, &ctxt); + } + if(req->ReconfigComplOutcome == RRCreconf_failure){ + LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n"); + } + else if(req->ReconfigComplOutcome == RRCreconf_success){ + LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n"); + if(ue_context_p->ue_context.DRB_configList!=NULL){ + LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); + uint8_t drb_id = ue_context_p->ue_context.DRB_configList->list.array[0]->drb_Identity; + rnti_t rnti = ue_context_p->ue_context.rnti; + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id); + LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); + MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, + sizeof(gtpv1u_gnb_tunnel_data_req_t)); + gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg); + req->pdusession_id = drb_id; + req->rnti = rnti; + req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead + extern instance_t DUuniqInstance; + itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); + + } + } + + /* Fill the UE context setup response ITTI message to send to F1AP */ + resp->gNB_CU_ue_id = req->gNB_CU_ue_id; + resp->rnti = ctxt.rnti; + if(DRB_configList){ + if(DRB_configList->list.count > 0){ + resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); + resp->drbs_to_be_setup_length = DRB_configList->list.count; + for (int i=0; ilist.count; i++){ + resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; + resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; + resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid; + resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr); + resp->drbs_to_be_setup[i].up_dl_tnl_length = 1; + } + } + else{ + LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n"); + } + } + if(SRB_configList){ + if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){ + resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t)); + resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; + for (int i=SRBs_before_new_addition; ilist.count; i++){ + resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity; + } + } + else{ + LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); + } + } + else{ + LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); + } + + //if(cellGroupConfig != NULL) { + resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t)); + resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, + 1024); + resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; + //} + itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); +} + static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = resp->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = resp->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -3396,8 +3513,8 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_NR_CellGroupConfig, (void **)&cellGroupConfig, - (uint8_t *)resp->du_to_cu_rrc_information, - (int) resp->du_to_cu_rrc_information_length); + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { AssertFatal(1==0,"Cell group config decode error\n"); @@ -3412,20 +3529,90 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ - LOG_I(NR_RRC, "rlc_BearerToAddModList not empty before filling it \n"); - free(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList); + int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ + ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, + cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + } } - ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, + else{ + LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); + ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + } } xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); + } else { + rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p); + } + free(cellGroupConfig->rlc_BearerToAddModList); free(cellGroupConfig); } +static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ + + f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + protocol_ctxt_t ctxt = { + .rnti = resp->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); + NR_CellGroupConfig_t *cellGroupConfig = NULL; + + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"Cell group config decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 ); + return; + } + //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); + + if(ue_context_p->ue_context.masterCellGroup == NULL){ + ue_context_p->ue_context.masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); + } + + if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ + if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ + int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ + ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, + cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + } + } + else{ + LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); + ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, + sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + } + } + LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n"); + xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); + + free(cellGroupConfig->rlc_BearerToAddModList); + free(cellGroupConfig); + } +} + unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } @@ -3590,7 +3777,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!! if (fd) { - if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == true) { fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n", ue_context_p->ue_id_rnti, ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi, @@ -3627,15 +3814,27 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { // Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) { - mac_remove_nr_ue(nrmac, ctxt_pP->rnti); - rrc_rlc_remove_ue(ctxt_pP); - pdcp_remove_UE(ctxt_pP); + if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->instance]->node_type)){ + mac_remove_nr_ue(nrmac, ctxt_pP->rnti); + rrc_rlc_remove_ue(ctxt_pP); + pdcp_remove_UE(ctxt_pP); - /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); - if (ue_context_p) { - rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); - LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + /* remove RRC UE Context */ + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); + if (ue_context_p) { + rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); + LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + } + } + // In case of CU trigger UE context release command towards the DU + else{ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p); + rel_cmd->rnti = ctxt_pP->rnti; + rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; + rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p); } } @@ -3722,73 +3921,31 @@ void *rrc_gnb_task(void *args_p) { nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); break; - /* Messages from MAC */ - case NR_RRC_MAC_CCCH_DATA_IND: - { - instance_t i; - for (i=0; inr_cellid == NR_RRC_MAC_CCCH_DATA_IND(msg_p).nr_cellid) - break; - } - AssertFatal(i!=RC.nb_nr_inst, "Cell_id not found\n"); - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - i, - GNB_FLAG_YES, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti, - msg_p->ittiMsgHeader.lte_time.frame, - msg_p->ittiMsgHeader.lte_time.slot); - LOG_I(NR_RRC,"Decoding CCCH : ue %d, inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", - ctxt.rnti, - i, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id, - &ctxt, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); - - if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) { - LOG_I(NR_RRC, "CCCH message has size %d > %d\n", - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE); - break; - } - - nr_rrc_gNB_decode_ccch(&ctxt, - (uint8_t *)NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id); - - if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container) { - free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container->buf); - free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container); - } - } - break; + case F1AP_INITIAL_UL_RRC_MESSAGE: + AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), + "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); + rrc_gNB_process_initial_ul_rrc_message(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); + break; /* Messages from PDCP */ - case NR_RRC_DCCH_DATA_IND: + case F1AP_UL_RRC_MESSAGE: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, - NR_RRC_DCCH_DATA_IND(msg_p).rnti, - msg_p->ittiMsgHeader.lte_time.frame, - msg_p->ittiMsgHeader.lte_time.slot); - LOG_D(NR_RRC,"Decoding DCCH : ue %d, inst %ld, ctxt %p, size %d\n", + F1AP_UL_RRC_MESSAGE(msg_p).rnti, + 0, + 0); + LOG_D(NR_RRC,"Decoding DCCH %d: ue %04x, inst %ld, ctxt %p, size %d\n", + F1AP_UL_RRC_MESSAGE(msg_p).srb_id, ctxt.rnti, instance, &ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - msg_name_p); + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); rrc_gNB_decode_dcch(&ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), NR_RRC_DCCH_DATA_IND(msg_p).sdu_p); - + F1AP_UL_RRC_MESSAGE(msg_p).srb_id, + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container, + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); + free(F1AP_UL_RRC_MESSAGE(msg_p).rrc_container); break; case NGAP_DOWNLINK_NAS: @@ -3821,17 +3978,30 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); break; - case NR_DU_RRC_DL_INDICATION: - rrc_process_DU_DL(msg_p, msg_name_p, instance); - break; + case NR_DU_RRC_DL_INDICATION: + rrc_process_DU_DL(msg_p, msg_name_p, instance); + break; - case F1AP_UE_CONTEXT_SETUP_REQ: - rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance); - break; + case F1AP_UE_CONTEXT_SETUP_REQ: + rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance); + break; - case F1AP_UE_CONTEXT_SETUP_RESP: - rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance); - break; + case F1AP_UE_CONTEXT_SETUP_RESP: + rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_MODIFICATION_RESP: + rrc_CU_process_ue_context_modification_response(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_MODIFICATION_REQ: + rrc_DU_process_ue_context_modification_request(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_RELEASE_CMD: + LOG_W(NR_RRC, "Received F1AP_UE_CONTEXT_RELEASE_CMD for processing at the RRC layer of the DU. Processing function " + "implementation is pending\n"); + break; /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: @@ -3929,17 +4099,6 @@ rrc_gNB_generate_SecurityModeCommand( size, rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else LOG_D(NR_RRC,"calling rrc_data_req :securityModeCommand\n"); nr_rrc_data_req(ctxt_pP, DCCH, @@ -3948,7 +4107,6 @@ rrc_gNB_generate_SecurityModeCommand( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif break; default : @@ -4001,17 +4159,6 @@ rrc_gNB_generate_UECapabilityEnquiry( size, rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, @@ -4019,7 +4166,6 @@ rrc_gNB_generate_UECapabilityEnquiry( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif break; default : @@ -4061,17 +4207,6 @@ rrc_gNB_generate_RRCRelease( rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size); memcpy (message_buffer, buffer, size); @@ -4094,7 +4229,6 @@ rrc_gNB_generate_RRCRelease( rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); ue_context_pP->ue_context.ue_release_timer_rrc = 1; } -#endif } void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) { @@ -4102,5 +4236,6 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS); RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe); itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 96ec634433..8f391417e0 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -307,7 +307,6 @@ nr_rrc_pdcp_config_security( //uint8_t *k_kdf = NULL; static int print_keys= 1; - /* Derive the keys from kgnb */ if (SRB_configList != NULL) { nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, @@ -475,7 +474,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt={0}; uint8_t pdu_sessions_done = 0; - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; int ret = 0; @@ -504,7 +502,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; if (nb_pdusessions_tosetup != 0) { - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) continue; @@ -513,6 +511,8 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done] = i+1; create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; + // To be developped: hardcoded first flow + create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].qos[0].qfi; create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer, @@ -709,7 +709,7 @@ rrc_gNB_process_security( rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP ) { - boolean_t changed = FALSE; + bool changed = false; NR_CipheringAlgorithm_t cipheringAlgorithm; e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ @@ -727,14 +727,14 @@ rrc_gNB_process_security( if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; - changed = TRUE; + changed = true; } integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms); if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; - changed = TRUE; + changed = true; } LOG_I (NR_RRC, "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", @@ -824,17 +824,6 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( case ngran_gNB: { // rrc_mac_config_req_gNB -#ifdef ITTI_SIM - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, length); - memcpy (message_buffer, buffer, length); - MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_UE_SIM, instance, message_p); - LOG_I(NR_RRC, "Send DL NAS message \n"); -#else /* Transfer data to PDCP */ nr_rrc_data_req ( &ctxt, @@ -844,7 +833,6 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } break; @@ -1004,6 +992,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; + create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi; memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t)*20); @@ -1050,7 +1039,46 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( // TEST // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE; // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0); - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p); + if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){ + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + } + else{ + /*Generate a UE context modification request message towards the DU to instruct the DU + *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p); + req->rnti = ue_context_p->ue_context.rnti; + req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; + req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; + req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; + req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; + + /*Instruction towards the DU for SRB2 configuration*/ + req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); + req->srbs_to_be_setup_length = 1; + f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; + SRBs[0].srb_id = 2; + SRBs[0].lcid = 2; + + /*Instruction towards the DU for DRB configuration and tunnel creation*/ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); + req->drbs_to_be_setup_length = 1; + f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; + LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); + DRBs[0].drb_id = 1; + DRBs[0].rlc_mode = RLC_MODE_AM; + DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); + DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; + DRBs[0].up_ul_tnl_length = 1; + DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr); + DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; + DRBs[0].up_dl_tnl_length = 1; + + itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); + } return(0); } } @@ -1088,17 +1116,17 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.gNB_ue_ngap_id = gNB_ue_ngap_id; { int j; - boolean_t is_treated[NGAP_MAX_PDUSESSION] = {FALSE}; + bool is_treated[NGAP_MAX_PDUSESSION] = {false}; uint8_t nb_of_failed_pdusessions = 0; for (i = 0; i < nb_pdusessions_tomodify; i++) { - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { continue; } //Check if same PDU session ID to handle multiple pdu sessions for (j = i+1; j < nb_pdusessions_tomodify; j++) { - if (is_treated[j] == FALSE && + if (is_treated[j] == false && NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[j].pdusession_id == NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id) { // handle multiple pdu session id @@ -1109,12 +1137,12 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; nb_of_failed_pdusessions++; - is_treated[i] = TRUE; - is_treated[j] = TRUE; + is_treated[i] = true; + is_treated[j] = true; } } // handle multiple pdu session id case - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { LOG_D(NR_RRC, "handle multiple pdu session id \n"); ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = @@ -1157,13 +1185,13 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[i].param.gtp_teid = ue_context_p->ue_context.pduSession[j].param.gtp_teid; - is_treated[i] = TRUE; + is_treated[i] = true; break; } } // handle Unknown pdu session ID - if (is_treated[i] == FALSE) { + if (is_treated[i] == false) { LOG_D(NR_RRC, "handle Unknown pdu session ID \n"); ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = @@ -1171,7 +1199,7 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; nb_of_failed_pdusessions++; - is_treated[i] = TRUE; + is_treated[i] = true; } } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index b8ff19b749..540ac5d075 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -37,61 +37,6 @@ #include "rrc_gNB_UE_context.h" -//------------------------------------------------------------------------------ -void nr_uid_linear_allocator_init( - nr_uid_allocator_t *const uid_pP -) -//------------------------------------------------------------------------------ -{ - memset(uid_pP, 0, sizeof(nr_uid_allocator_t)); -} - -//------------------------------------------------------------------------------ -uid_nr_t nr_uid_linear_allocator_new(gNB_RRC_INST *const rrc_instance_pP) -//------------------------------------------------------------------------------ -{ - unsigned int i; - unsigned int bit_index = 1; - uid_nr_t uid = 0; - nr_uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; - - for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { - if (uia_p->bitmap[i] != UINT_MAX) { - bit_index = 1; - uid = 0; - - while ((uia_p->bitmap[i] & bit_index) == bit_index) { - bit_index = bit_index << 1; - uid += 1; - } - - uia_p->bitmap[i] |= bit_index; - return uid + (i*sizeof(unsigned int)*8); - } - } - - return UINT_MAX; -} - - -//------------------------------------------------------------------------------ -void -nr_uid_linear_allocator_free( - gNB_RRC_INST *rrc_instance_pP, - uid_nr_t uidP -) -//------------------------------------------------------------------------------ -{ - unsigned int i = uidP/sizeof(unsigned int)/8; - unsigned int bit = uidP % (sizeof(unsigned int) * 8); - unsigned int value = ~(0x00000001 << bit); - - if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { - rrc_instance_pP->uid_allocator.bitmap[i] &= value; - } -} - - //------------------------------------------------------------------------------ int rrc_gNB_compare_ue_rnti_id( struct rrc_gNB_ue_context_s *c1_pP, struct rrc_gNB_ue_context_s *c2_pP) @@ -130,7 +75,7 @@ rrc_gNB_allocate_new_UE_context( } memset(new_p, 0, sizeof(struct rrc_gNB_ue_context_s)); - new_p->local_uid = nr_uid_linear_allocator_new(rrc_instance_pP); + new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; @@ -177,12 +122,12 @@ void rrc_gNB_free_mem_UE_context( { LOG_T(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + PROTOCOL_NR_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); + //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); + //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); // empty the internal fields of the UE context here } @@ -195,25 +140,25 @@ void rrc_gNB_remove_ue_context( //------------------------------------------------------------------------------ { if (rrc_instance_pP == NULL) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Bad RRC instance\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Bad RRC instance\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); return; } if (ue_context_pP == NULL) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); return; } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_pP); - nr_uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid); free(ue_context_pP); rrc_instance_pP->Nb_ue --; LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + PROTOCOL_NR_RRC_CTXT_UE_FMT" Removed UE context\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); } //----------------------------------------------------------------------------- diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 73bd93e737..4009f2617f 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -34,27 +34,6 @@ #include "COMMON/platform_types.h" #include "nr_rrc_defs.h" - -void -nr_uid_linear_allocator_init( - nr_uid_allocator_t* const uid_pP -); - -uid_t -nr_uid_linear_allocator_new( - gNB_RRC_INST* rrc_instance_pP -); - - -void -nr_uid_linear_allocator_free( - gNB_RRC_INST* rrc_instance_pP, - uid_t uidP -); - - - - int rrc_gNB_compare_ue_rnti_id( struct rrc_gNB_ue_context_s* c1_pP, struct rrc_gNB_ue_context_s* c2_pP diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 07a6bd85be..b3eada8136 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -349,7 +349,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ // configure MAC and RLC if (NODE_IS_DU(rrc->node_type)) { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -362,7 +361,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_context.secondaryCellGroup); } else { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index a6fef46c34..08baeb3d45 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -47,9 +47,6 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "nr_rrc_config.h" -#define false 0 -#define true 1 - void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) { int b = 0; @@ -85,9 +82,9 @@ void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) { void fill_default_nsa_downlinkBWP(NR_BWP_Downlink_t *bwp, long bwp_loop, - NR_CellGroupConfig_t *secondaryCellGroup, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_ServingCellConfigCommon_t *servingcellconfigcommon, + const NR_CellGroupConfig_t *secondaryCellGroup, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *servingcellconfigcommon, const gNB_RrcConfigurationReq *configuration, NR_UE_NR_Capability_t *uecap, int dl_antenna_ports, @@ -337,128 +334,26 @@ void fill_default_nsa_uplinkBWP(NR_BWP_Uplink_t *ubwp, /// BWP dedicated configuration - if (!ubwp->bwp_Dedicated) { + if (!ubwp->bwp_Dedicated) ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated)); - } + + int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + ubwp->bwp_Dedicated->pucch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->choice.setup=pucch_Config; + pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=1; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=2; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); - pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); - int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); - - pucchres0->pucch_ResourceId=1; - pucchres0->startingPRB= (8 + uid) % curr_bwp; - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - - pucchres2->pucch_ResourceId=2; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - - // for scheduling requestresource - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10; - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 1; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - - pucch_Config->schedulingRequestResourceToReleaseList=NULL; - pucch_Config->multi_CSI_PUCCH_ResourceList=NULL; - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - *delay[i] = i + configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); - pucch_Config->spatialRelationInfoToReleaseList=NULL; - pucch_Config->pucch_PowerControl=calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = 0; - pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); - NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); - p00->p0_PUCCH_Id=1; - p00->p0_PUCCH_Value = 0; - ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); - pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; + scheduling_request_config(servingcellconfigcommon, pucch_Config); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -648,40 +543,33 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(*secondaryCellGroup->rlc_BearerToAddModList)); ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig); - secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig)); - secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL; - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig)); - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); - NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf)); - SchedulingRequestConf->schedulingRequestId = 0; //Could be changed - SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer)); - *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16; - SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32; - ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf); - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL; + NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = secondaryCellGroup->mac_CellGroupConfig; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; - secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config)); - secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; - secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList)); + mac_CellGroupConfig=calloc(1,sizeof(*mac_CellGroupConfig)); + mac_CellGroupConfig->drx_Config = NULL; + + mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*mac_CellGroupConfig->bsr_Config)); + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; + mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*mac_CellGroupConfig->tag_Config)); + mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; + mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); struct NR_TAG *tag=calloc(1,sizeof(*tag)); tag->tag_Id = 0; tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; - ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); - secondaryCellGroup->mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config)); - secondaryCellGroup->mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup)); - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR=false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->dummy=false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = NR_PHR_Config__phr_ModeOtherCG_real; - secondaryCellGroup->mac_CellGroupConfig->skipUplinkTxDynamic=false; - secondaryCellGroup->mac_CellGroupConfig->ext1 = NULL; + ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); + mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config)); + mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; + mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); + mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3; + mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR=false; + mac_CellGroupConfig->phr_Config->choice.setup->dummy=false; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = false; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = NR_PHR_Config__phr_ModeOtherCG_real; + mac_CellGroupConfig->skipUplinkTxDynamic=false; + mac_CellGroupConfig->ext1 = NULL; secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig)); secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH=NULL; secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH=NULL; @@ -1140,6 +1028,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList= NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList = NULL; + mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); + mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); + struct NR_SchedulingRequestToAddMod *schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); + schedulingrequestlist->schedulingRequestId = 0; + schedulingrequestlist->sr_ProhibitTimer = NULL; + schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; + ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig)); NR_PUSCH_ServingCellConfig_t *pusch_scc = calloc(1,sizeof(*pusch_scc)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->present = NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 6f0c7fc27f..8907ff315a 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -34,6 +34,7 @@ #include "rrc_proto.h" #include "assertions.h" #include "rrc_vars.h" +#include "MAC/mac.h" typedef uint32_t channel_t; @@ -181,6 +182,6 @@ rrc_data_req_nr_ue( TASK_PDCP_UE, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 50ec32772d..bf4f053ba6 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1320,11 +1320,11 @@ nr_rrc_ue_process_masterCellGroup( //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) } - if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ + if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) } - if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ + if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) } } @@ -1342,12 +1342,6 @@ static void rrc_ue_generate_RRCSetupComplete( int nas_msg_length; if (AMF_MODE_ENABLED) { -#if defined(ITTI_SIM) - as_nas_info_t initialNasMsg; - generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); - nas_msg = (char*)initialNasMsg.data; - nas_msg_length = initialNasMsg.length; -#else if (get_softmodem_params()->sa) { as_nas_info_t initialNasMsg; generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); @@ -1357,7 +1351,6 @@ static void rrc_ue_generate_RRCSetupComplete( 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; } -#endif } else { nas_msg = nr_nas_attach_req_imsi; nas_msg_length = sizeof(nr_nas_attach_req_imsi); @@ -1381,18 +1374,6 @@ static void rrc_ue_generate_RRCSetupComplete( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE, TASK_RRC_GNB_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = 1; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); -#endif } int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){ @@ -1711,19 +1692,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB } LOG_T(NR_RRC, "\n"); - #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - #else rrc_data_req_nr_ue (ctxt_pP, DCCH, nr_rrc_mui++, @@ -1731,7 +1699,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - #endif } else LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", securityModeCommand->criticalExtensions.present); @@ -1777,19 +1744,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB //printf("\n"); /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff; UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */ - -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, - NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, gNB_index, message_p); -#endif } } @@ -2014,7 +1968,7 @@ nr_rrc_ue_establish_srb2( int i, cnt; if( radioBearerConfig->srb3_ToRelease != NULL){ - if( *radioBearerConfig->srb3_ToRelease == TRUE){ + if( *radioBearerConfig->srb3_ToRelease == true){ //TODO (release the PDCP entity and the srb-Identity of the SRB3.) } } @@ -2254,19 +2208,6 @@ nr_rrc_ue_establish_srb2( nr_rrc_mui, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), DCCH); - #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size); - memcpy (message_buffer, buffer, size); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - - #else rrc_data_req_nr_ue ( ctxt_pP, DCCH, @@ -2275,8 +2216,6 @@ nr_rrc_ue_establish_srb2( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - #endif - } // from NR SRB1 @@ -2523,22 +2462,6 @@ nr_rrc_ue_establish_srb2( length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); /* Transfer data to PDCP */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); - memcpy (message_buffer, buffer, length); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - else - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH1; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt.instance, message_p); - -#else // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { rrc_data_req_nr_ue (&ctxt, @@ -2555,7 +2478,6 @@ nr_rrc_ue_establish_srb2( length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } -#endif break; } @@ -2699,19 +2621,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( } LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); -#else rrc_data_req_nr_ue ( ctxt_pP, DCCH, @@ -2720,7 +2629,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } } } @@ -2739,19 +2647,6 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( rrcReestablishment->rrc_TransactionIdentifier); LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); - memcpy (message_buffer, buffer, length); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - -#endif } void *recv_msgs_from_lte_ue(void *args_p) diff --git a/openair2/SDAP/nr_sdap/nr_sdap.c b/openair2/SDAP/nr_sdap/nr_sdap.c index 74ef93aff7..6457843ae0 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.c +++ b/openair2/SDAP/nr_sdap/nr_sdap.c @@ -21,19 +21,22 @@ #include "nr_sdap.h" -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id) { +uint8_t nas_qfi; +uint8_t nas_pduid; + +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id) { nr_sdap_entity_t *sdap_entity; sdap_entity = nr_sdap_get_entity(ctxt_p->rnti, pdusession_id); @@ -42,19 +45,19 @@ boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, return 0; } - boolean_t ret = sdap_entity->tx_entity(sdap_entity, - ctxt_p, - srb_flag, - rb_id, - mui, - confirm, - sdu_buffer_size, - sdu_buffer, - pt_mode, - sourceL2Id, - destinationL2Id, - qfi, - rqi); + bool ret = sdap_entity->tx_entity(sdap_entity, + ctxt_p, + srb_flag, + rb_id, + mui, + confirm, + sdu_buffer_size, + sdu_buffer, + pt_mode, + sourceL2Id, + destinationL2Id, + qfi, + rqi); return ret; } @@ -84,3 +87,9 @@ void sdap_data_ind(rb_id_t pdcp_entity, buf, size); } + +void set_qfi_pduid(uint8_t qfi, uint8_t pduid){ + nas_qfi = qfi; + nas_pduid = pduid; + return; +} diff --git a/openair2/SDAP/nr_sdap/nr_sdap.h b/openair2/SDAP/nr_sdap/nr_sdap.h index cd702cfd7f..ea4fe7f74d 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.h +++ b/openair2/SDAP/nr_sdap/nr_sdap.h @@ -32,20 +32,19 @@ * Downlink - gNB * Uplink - nrUE */ -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id - ); +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id); /* * TS 37.324 4.4 Functions @@ -63,4 +62,6 @@ void sdap_data_ind(rb_id_t pdcp_entity, int size ); +void set_qfi_pduid(uint8_t qfi, uint8_t pduid); + #endif diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 79532748d2..5e3627296c 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -46,23 +46,22 @@ void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_u return; } -static boolean_t nr_sdap_tx_entity(nr_sdap_entity_t *entity, - protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi - ) { +static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, + protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi) { /* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */ int offset=0; - boolean_t ret=false; + bool ret = false; /*Hardcode DRB ID given from upper layer (ue/enb_tun_read_thread rb_id), it will change if we have SDAP*/ rb_id_t sdap_drb_id = rb_id; int pdcp_ent_has_sdap = 0; @@ -297,7 +296,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, } } -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap){ +void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool hasSdap) { if(qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && drb > 0 && @@ -390,7 +389,7 @@ void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap, uint16_t rnti, int pdusession_id, - boolean_t is_defaultDRB, + bool is_defaultDRB, uint8_t drb_identity, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount) diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index b46e5bf4e3..635289d4d4 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -64,7 +64,7 @@ typedef struct nr_sdap_ul_hdr_s { typedef struct qfi2drb_s { rb_id_t drb_id; - boolean_t hasSdap; + bool hasSdap; } qfi2drb_t; void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); @@ -75,7 +75,7 @@ typedef struct nr_sdap_entity_s { int pdusession_id; qfi2drb_t qfi2drb_table[SDAP_MAX_QFI]; - void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap); + void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, bool hasSdap); void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi); rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t upper_layer_rb_id); @@ -84,20 +84,19 @@ typedef struct nr_sdap_entity_s { void (*sdap_submit_ctrl_pdu)(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); - boolean_t (*tx_entity)(struct nr_sdap_entity_s *entity, - protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi - ); + bool (*tx_entity)(struct nr_sdap_entity_s *entity, + protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi); void (*rx_entity)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, @@ -114,7 +113,7 @@ typedef struct nr_sdap_entity_s { } nr_sdap_entity_t; /* QFI to DRB Mapping Related Function */ -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap); +void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool hasSdap); /* QFI to DRB Mapping Related Function */ void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi); @@ -168,7 +167,7 @@ void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap, uint16_t rnti, int pdusession_id, - boolean_t is_defaultDRB, + bool is_defaultDRB, uint8_t default_DRB, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount); diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c deleted file mode 100644 index a6ac444e45..0000000000 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ /dev/null @@ -1,664 +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 itti_sim.c - * \brief simulator for itti message from node to UE - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ - - -#include - - -#include "T.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -#include - -#include "common/ran_context.h" - -#include "common/config/config_userapi.h" -#include "common/utils/load_module_shlib.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "PHY/phy_vars.h" -#include "SCHED/sched_common_vars.h" -#include "LAYER2/MAC/mac_vars.h" -#include "RRC/LTE/rrc_vars.h" -#include "gnb_config.h" -#include "SIMULATION/TOOLS/sim.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif - -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" - -#include "intertask_interface.h" - - -#include "system.h" -#include -#include "PHY/TOOLS/phy_scope_interface.h" -#include "PHY/TOOLS/nr_phy_scope.h" -#include "stats.h" -#include "nr-softmodem.h" -#include "executables/softmodem-common.h" -#include "executables/thread-common.h" -#include "NB_IoT_interface.h" -#include "x2ap_eNB.h" -#include "ngap_gNB.h" -#include "RRC/NR_UE/rrc_proto.h" -#include "RRC/NR_UE/rrc_vars.h" -#include "openair3/NAS/UE/nas_ue_task.h" -#include -#include -#if ITTI_SIM -#include "nr_nas_msg_sim.h" -#endif - -pthread_cond_t nfapi_sync_cond; -pthread_mutex_t nfapi_sync_mutex; -int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex - -uint32_t timing_advance = 0; -uint64_t num_missed_slots=0; - -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - -nrUE_params_t nrUE_params; -nrUE_params_t *get_nrUE_params(void) { - return &nrUE_params; -} - -void processSlotTX(void *arg) {} - -THREAD_STRUCT thread_struct; -pthread_cond_t sync_cond; -pthread_mutex_t sync_mutex; -int sync_var=-1; //!< protected by mutex \ref sync_mutex. -int config_sync_var=-1; - -openair0_config_t openair0_cfg[MAX_CARDS]; - -//volatile int start_gNB = 0; -volatile int oai_exit = 0; - -//static int wait_for_sync = 0; - -unsigned int mmapped_dma=0; -int single_thread_flag=1; - -int8_t threequarter_fs=0; - -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; - -//Temp fix for inexistent NR upper layer -unsigned char NB_gNB_INST = 1; - - -int UE_scan = 1; -int UE_scan_carrier = 0; -runmode_t mode = normal_txrx; -static double snr_dB=20; - -FILE *input_fd=NULL; - -int chain_offset=0; - - -uint8_t dci_Format = 0; -uint8_t agregation_Level =0xFF; - -uint8_t nb_antenna_tx = 1; -uint8_t nb_antenna_rx = 1; - -char ref[128] = "internal"; -char channels[128] = "0"; - -int otg_enabled; - -extern void *udp_eNB_task(void *args_p); - -int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; - - -double cpuf; - -extern char uecap_xer[1024]; -char uecap_xer_in=0; - -/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed - * this is very hackish - find a proper solution - */ -uint8_t abstraction_flag=0; - -/* forward declarations */ -void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); - -/*---------------------BMC: timespec helpers -----------------------------*/ - -struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - -struct timespec clock_difftime(struct timespec start, struct timespec end) { - struct timespec temp; - - 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; - } - - return temp; -} - - - -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KBLU "\x1B[34m" -#define RESET "\033[0m" - - -void exit_function(const char *file, const char *function, const int line, const char *s) { - int ru_id; - - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } - - oai_exit = 1; - - if (RC.ru == NULL) - exit(-1); // likely init not completed, prevent crash or hang, exit now... - - for (ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } - - sleep(1); //allow lte-softmodem threads to exit first - exit(1); -} - -void wait_gNBs(void) { - int i; - int waiting=1; - - while (waiting==1) { - printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst); - usleep(50*1000); - waiting=0; - - for (i=0; iconfigured==0) { - waiting=1; - break; - } - } - } - - printf("gNB L1 are configured\n"); -} - -void wait_RUs(void) { - LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); - // wait for all RUs to be configured over fronthaul - pthread_mutex_lock(&RC.ru_mutex); - - while (RC.ru_mask>0) { - pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); - printf("RC.ru_mask:%02lx\n", RC.ru_mask); - } - - pthread_mutex_unlock(&RC.ru_mutex); - LOG_I(PHY,"RUs configured\n"); -} - - -int stop_L1L2(module_id_t gnb_id) { - return 0; -} - -int restart_L1L2(module_id_t gnb_id) { - return 0; -} - -int create_gNB_tasks(uint32_t gnb_nb) { - LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); - itti_wait_ready(1); - - - if (gnb_nb > 0) { - if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } - if (is_x2ap_enabled()) { - if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ - LOG_E(X2AP, "Create task for X2AP failed\n"); - } - } - else { - LOG_I(X2AP, "X2AP is disabled.\n"); - } - } - - if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) { - if (gnb_nb > 0) { - if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for NGAP failed\n"); - return -1; - } - - - if(!emulate_rf){ - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } - - if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } - } - } - - - if (gnb_nb > 0) { - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } - LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); - - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; - } - } - - return 0; -} - - -static void get_options(void) { - - - paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; - - CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - get_common_options(SOFTMODEM_GNB_BIT ); - config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); - - - - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - memset((void *)&RC,0,sizeof(RC)); - /* Read RC configuration file */ - NRRCConfig(); - NB_gNB_INST = RC.nb_nr_inst; - NB_RU = RC.nb_RU; - printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); - } - -} - - -void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], - NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) -{ - for (int CC_id=0; CC_idssb_config.scs_common.value = 1; - config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD - config[CC_id]->carrier_config.dl_grid_size[1].value = 106; - config[CC_id]->carrier_config.ul_grid_size[1].value = 106; - config[CC_id]->cell_config.phy_cell_id.value = 0; - } -} - -/* - * helper function to terminate a certain ITTI task - */ -void terminate_task(task_id_t task_id, module_id_t mod_id) { - LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); - MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE); - itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); -} - -//extern void free_transport(PHY_VARS_gNB *); -extern void nr_phy_free_RU(RU_t *); - -statis void init_pdcp(void) { - //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { - pdcp_layer_init(); - uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? - (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; - - if (IS_SOFTMODEM_NOS1) { - printf("IS_SOFTMODEM_NOS1 option enabled \n"); - pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; - } - - pdcp_module_init(pdcp_initmask, 0); - - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); -} - - -int create_tasks_nrue(uint32_t ue_nb) { - LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); - itti_wait_ready(1); - - if (ue_nb > 0) { - LOG_D(NR_RRC, "create TASK_RRC_NRUE\n"); - if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for RRC UE failed\n"); - return -1; - } - - LOG_D(NR_RRC,"create TASK_NAS_NRUE\n"); - if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NAS UE failed\n"); - return -1; - } - } - - - itti_wait_ready(0); - return 0; -} - - -void *itti_sim_ue_rrc_task( void *args_p) { - MessageDef *msg_p, *message_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - itti_mark_task_ready (TASK_RRC_UE_SIM); - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RRC_UE_SIM, &msg_p); - instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); - ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task (); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - case GNB_RRC_BCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_BCCH_DATA_IND); - memset (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = GNB_RRC_BCCH_DATA_IND(msg_p).size; - memcpy (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).size); - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - case GNB_RRC_CCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); - printf("receive GNB_RRC_CCCH_DATA_IND\n"); - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).size); - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = GNB_RRC_CCCH_DATA_IND(msg_p).size; - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - case GNB_RRC_DCCH_DATA_IND: - printf("receive GNB_RRC_DCCH_DATA_IND\n"); - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_DCCH_DATA_IND); - NR_RRC_DCCH_DATA_IND (message_p).dcch_index = GNB_RRC_DCCH_DATA_IND(msg_p).rbid; - NR_RRC_DCCH_DATA_IND (message_p).sdu_size = GNB_RRC_DCCH_DATA_IND(msg_p).size; - NR_RRC_DCCH_DATA_IND (message_p).sdu_p = GNB_RRC_DCCH_DATA_IND(msg_p).sdu; - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; - } -} - - -void *itti_sim_gnb_rrc_task( void *args_p) { - MessageDef *msg_p, *message_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - itti_mark_task_ready (TASK_RRC_GNB_SIM); - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RRC_GNB_SIM, &msg_p); - instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); - ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task (); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - case UE_RRC_CCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = UE_RRC_CCCH_DATA_IND(msg_p).size; - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).size); - itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); - break; - case UE_RRC_DCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_DCCH_DATA_IND); - NR_RRC_DCCH_DATA_IND (message_p).sdu_size = UE_RRC_DCCH_DATA_IND(msg_p).size; - NR_RRC_DCCH_DATA_IND (message_p).dcch_index = UE_RRC_DCCH_DATA_IND(msg_p).rbid; - NR_RRC_DCCH_DATA_IND (message_p).sdu_p = UE_RRC_DCCH_DATA_IND(msg_p).sdu; - itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); - break; - - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; - } -} - - -int main( int argc, char **argv ) -{ - start_background_system(); - - ///static configuration for NR at the moment - if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - set_softmodem_sighandler(); -#ifdef DEBUG_CONSOLE - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); -#endif - - logInit(); - //set_latency_target(); - printf("Reading in command-line options\n"); - get_options (); - - if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - - AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; -// AMF_MODE_ENABLED = 0; - NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; - -#if T_TRACER - T_Config_Init(); -#endif - //randominit (0); - set_taus_seed (0); - printf("configuring for RAU/RRU\n"); - - if (opp_enabled ==1) { - reset_opp_meas(); - } - - cpuf=get_cpu_freq_GHz(); - itti_init(TASK_MAX, tasks_info); - - init_opt(); - - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - - if(IS_SOFTMODEM_NOS1) - init_pdcp(); - - if (RC.nb_nr_inst > 0) { - nr_read_config_and_init(); - // don't create if node doesn't connect to RRC/S1/GTP - AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); - for (int gnb_id = 0; gnb_id < RC.nb_nr_inst; gnb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); - NRRRC_CONFIGURATION_REQ(msg_p) = RC.nrrrc[gnb_id]->configuration; - itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); - } - } else { - printf("No ITTI, Initializing L1\n"); - return 0; - } - - if(itti_create_task (TASK_RRC_GNB_SIM, itti_sim_gnb_rrc_task, NULL) < 0){ - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - openair_rrc_top_init_ue_nr("./"); - - if (create_tasks_nrue(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - if(itti_create_task (TASK_RRC_UE_SIM, itti_sim_ue_rrc_task, NULL) < 0){ - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - - printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - // wait for end of program - printf("TYPE TO TERMINATE\n"); - - usleep(100000); - protocol_ctxt_t ctxt; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - - - ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[0]); - - if(ue_context_p == NULL){ - printf("ue_context_p == NULL"); - } - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - 0, - ENB_FLAG_YES, - 0, - 0, - 0); - NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED; - - nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0); - - printf("Entering ITTI signals handler\n"); - itti_wait_tasks_end(); - printf("Returned from ITTI signal handler\n"); - oai_exit=1; - printf("oai_exit=%d\n",oai_exit); - - printf("stopping MODEM threads\n"); - - - /* release memory used by the RU/gNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); - - logClean(); - printf("Bye.\n"); - return 0; -} - - - diff --git a/openair2/UTIL/OMG/defs.h b/openair2/UTIL/OMG/defs.h index 06c9bf6e73..1102a69cc5 100644 --- a/openair2/UTIL/OMG/defs.h +++ b/openair2/UTIL/OMG/defs.h @@ -29,12 +29,6 @@ #include -// TYPEDEFS - -#define true 1 -#define false 0 - -//typedef char bool; #include #include "omg_constants.h" diff --git a/openair2/X2AP/x2ap_common.c b/openair2/X2AP/x2ap_common.c index 93a8c32513..a687b90666 100644 --- a/openair2/X2AP/x2ap_common.c +++ b/openair2/X2AP/x2ap_common.c @@ -31,27 +31,6 @@ #include "x2ap_common.h" #include "X2AP_X2AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t x2ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair2/X2AP/x2ap_common.h b/openair2/X2AP/x2ap_common.h index a2f903a737..e7b86c77b9 100644 --- a/openair2/X2AP/x2ap_common.h +++ b/openair2/X2AP/x2ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef X2AP_COMMON_H_ +#define X2AP_COMMON_H_ #include "X2AP_ProtocolIE-Field.h" #include "X2AP_X2AP-PDU.h" @@ -35,9 +33,6 @@ #include "X2AP_asn_constant.h" #include "intertask_interface.h" -#ifndef X2AP_COMMON_H_ -#define X2AP_COMMON_H_ - /** @defgroup _x2ap_impl_ X2AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ @@ -52,11 +47,6 @@ # define X2AP_PORT 36422 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/COMMON/security_types.h b/openair3/COMMON/security_types.h index eb55e44d77..5494ffd994 100644 --- a/openair3/COMMON/security_types.h +++ b/openair3/COMMON/security_types.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif +#ifndef SECURITY_TYPES_H_ +#define SECURITY_TYPES_H_ #if !defined(HAVE_UINT128_T) # include @@ -31,8 +29,6 @@ #include #include -#ifndef SECURITY_TYPES_H_ -#define SECURITY_TYPES_H_ #define RAND_LENGTH_BITS (128) #define RAND_LENGTH_OCTETS (RAND_LENGTH_BITS/8) diff --git a/openair3/M3AP/m3ap_common.c b/openair3/M3AP/m3ap_common.c index 5501997638..e43275d96c 100644 --- a/openair3/M3AP/m3ap_common.c +++ b/openair3/M3AP/m3ap_common.c @@ -31,27 +31,6 @@ #include "m3ap_common.h" #include "M3AP_M3AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t m3ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair3/M3AP/m3ap_common.h b/openair3/M3AP/m3ap_common.h index 7f68510314..75c60db71a 100644 --- a/openair3/M3AP/m3ap_common.h +++ b/openair3/M3AP/m3ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef M3AP_COMMON_H_ +#define M3AP_COMMON_H_ #include "M3AP_ProtocolIE-Field.h" #include "M3AP_M3AP-PDU.h" @@ -35,8 +33,6 @@ #include "M3AP_asn_constant.h" #include "intertask_interface.h" -#ifndef M3AP_COMMON_H_ -#define M3AP_COMMON_H_ /** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation * @ingroup _ref_implementation_ @@ -52,11 +48,6 @@ # define M3AP_PORT 36444 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/NAS/COMMON/UTIL/nas_timer.c b/openair3/NAS/COMMON/UTIL/nas_timer.c index 8448d9a78c..b67a3bc232 100644 --- a/openair3/NAS/COMMON/UTIL/nas_timer.c +++ b/openair3/NAS/COMMON/UTIL/nas_timer.c @@ -121,7 +121,7 @@ static nas_timer_database_t _nas_timer_db = { static void _nas_timer_db_init(void); static int _nas_timer_db_get_id(void); -static int _nas_timer_db_is_active(int id); +static bool _nas_timer_db_is_active(int id); static nas_timer_entry_t *_nas_timer_db_create_entry(long sec, nas_timer_callback_t cb, void *args); static void _nas_timer_db_delete_entry(int id); @@ -130,7 +130,7 @@ static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t *te); static int _nas_timer_db_insert(timer_queue_t *entry); static nas_timer_entry_t *_nas_timer_db_remove_entry(int id); -static int _nas_timer_db_remove(timer_queue_t *entry); +static bool _nas_timer_db_remove(timer_queue_t *entry); /* * ----------------------------------------------------------------------------- @@ -408,12 +408,12 @@ static int _nas_timer_db_get_id(void) ** Others: _nas_timer_db ** ** ** ** Outputs: None ** - ** Return: TRUE if the timer entry is active; FALSE ** + ** Return: true if the timer entry is active; false ** ** if it is not an active timer entry. ** ** Others: None ** ** ** ***************************************************************************/ -static int _nas_timer_db_is_active(int id) +static bool _nas_timer_db_is_active(int id) { return ( (id != NAS_TIMER_INACTIVE_ID) && (_nas_timer_db.tq[id].id != NAS_TIMER_INACTIVE_ID) ); @@ -562,11 +562,11 @@ static int _nas_timer_db_insert(timer_queue_t *entry) } else { /* The new entry is the first entry of the list */ _nas_timer_db.head = entry; - return TRUE; + return true; } /* The new entry is NOT the first entry of the list */ - return FALSE; + return false; } /**************************************************************************** @@ -588,7 +588,7 @@ static int _nas_timer_db_insert(timer_queue_t *entry) ***************************************************************************/ static nas_timer_entry_t *_nas_timer_db_remove_entry(int id) { - int restart; + bool restart; /* The identifier of the timer is valid within the timer queue */ assert(_nas_timer_db.tq[id].id == id); @@ -622,7 +622,7 @@ static nas_timer_entry_t *_nas_timer_db_remove_entry(int id) return (_nas_timer_db.tq[id].entry); } -static int _nas_timer_db_remove(timer_queue_t *entry) +static bool _nas_timer_db_remove(timer_queue_t *entry) { /* Update the pointer from the previous entry */ /* prev ---> entry ---> next */ @@ -644,12 +644,12 @@ static int _nas_timer_db_remove(timer_queue_t *entry) if (_nas_timer_db.head != NULL) { /* Other timers are scheduled to expire */ - return TRUE; + return true; } } /* The entry was NOT the first entry of the list */ - return FALSE; + return false; } /* diff --git a/openair3/NAS/COMMON/UTIL/socket.c b/openair3/NAS/COMMON/UTIL/socket.c index 53a6ec8823..20c071203d 100644 --- a/openair3/NAS/COMMON/UTIL/socket.c +++ b/openair3/NAS/COMMON/UTIL/socket.c @@ -397,7 +397,7 @@ static int _socket_set_option(int sfd) * and it will simply open another socket on the same port and * continue listening. */ - optval = TRUE; + optval = true; if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { return RETURNerror; @@ -405,12 +405,12 @@ static int _socket_set_option(int sfd) /* IPV6_V6ONLY socket option * ------------------------- - * When option is set to TRUE, the socket is restricted to sending and + * When option is set to true, the socket is restricted to sending and * receiving IPv6 packets only. - * When option is set to FALSE, the socket can be used to send and receive + * When option is set to false, the socket can be used to send and receive * packets to and from an IPv6 address or an IPv4-mapped IPv6 address. */ - optval = FALSE; + optval = false; if (setsockopt (sfd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)) < 0) { return RETURNerror; diff --git a/openair3/NAS/COMMON/UTIL/stty.c b/openair3/NAS/COMMON/UTIL/stty.c index eceb0b06b1..fe87a63e44 100644 --- a/openair3/NAS/COMMON/UTIL/stty.c +++ b/openair3/NAS/COMMON/UTIL/stty.c @@ -192,7 +192,7 @@ static sttyset_t stty_params[] = { { NULL, 0, 0, 0 } }; -static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon); +static int _stty_set_this(struct termios *term, const sttyset_t *p, bool turnon); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -207,7 +207,7 @@ static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon); ** ** ** Inputs: p: The TTY parameters ** ** turnon: Indicate whether the parameter should be ** - ** turned on (TRUE) or turned off (FALSE) ** + ** turned on (true) or turned off (false) ** ** Others: None ** ** ** ** Outputs: term: The termios structure to fill ** @@ -223,7 +223,7 @@ int stty_set(int fd, const char *params) register char *s; struct termios term; register int i; - int mode; + bool mode; /* Get current tty attributes */ if ( tcgetattr(fd, &term) < 0 ) { @@ -234,10 +234,10 @@ int stty_set(int fd, const char *params) p = strtok(s," \t\n"); while (p && (rc != RETURNerror)) { - mode = 1; + mode = true; if ( *p == '-' ) { - mode = 0; + mode = false; p++; } @@ -275,7 +275,7 @@ int stty_set(int fd, const char *params) ** ** ** Inputs: p: The TTY parameters ** ** turnon: Indicate whether the parameter should be ** - ** turned on (TRUE) or turned off (FALSE) ** + ** turned on (true) or turned off (false) ** ** Others: None ** ** ** ** Outputs: term: The termios structure to fill ** @@ -283,7 +283,7 @@ int stty_set(int fd, const char *params) ** Others: None ** ** ** ***************************************************************************/ -static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon) +static int _stty_set_this(struct termios *term, const sttyset_t *p, bool turnon) { int rc = RETURNok; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e151fec9b4..43c3b56aa4 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -44,6 +44,7 @@ #include #include #include +#include "openair2/SDAP/nr_sdap/nr_sdap.h" uint8_t *registration_request_buf; uint32_t registration_request_len; @@ -915,7 +916,7 @@ void *nas_nrue_task(void *args_p) payload_container = pdu_buffer + offset; } offset = 0; - + uint8_t pdu_id = *(pdu_buffer+14); while(offset < payload_container_length) { // Fixme: this is not good 'type' 0x29 searching in TLV like structure // AND fix dirsty code copy hereafter of the same!!! @@ -929,9 +930,13 @@ void *nas_nrue_task(void *args_p) *(payload_container+offset+3), *(payload_container+offset+4), *(payload_container+offset+5), *(payload_container+offset+6)); nas_config(1,third_octet,fourth_octet,"oaitun_ue"); - break; } } + if (*(payload_container + offset) == 0x79) { + uint8_t qfi = *(payload_container+offset+3); + set_qfi_pduid(qfi, pdu_id); + break; + } offset++; } } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 9655f87130..abdc5b2e75 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -80,7 +80,6 @@ typedef struct { uint8_t kgnb[32]; } ue_sa_security_key_t; - typedef enum fgs_protocol_discriminator_e { /* Protocol discriminator identifier for 5GS Mobility Management */ FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E, diff --git a/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c b/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c index bbc37d18a3..387c3de3a8 100644 --- a/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c +++ b/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c @@ -120,12 +120,12 @@ static socket_id_t * _as_simulator_mme_sid = NULL; /* * UE NAS process connection manager's running indicator */ -static int _as_simulator_ue_is_running = FALSE; +static bool _as_simulator_ue_is_running = false; /* * MME NAS process connection manager's running indicator */ -static int _as_simulator_mme_is_running = FALSE; +static bool _as_simulator_mme_is_running = false; static int _set_signal_handler(int signal, void (handler)(int)); static void _signal_handler(int signal_number); @@ -307,8 +307,8 @@ static void _signal_handler(int signal_number) { printf("\nWARNING\t: %s - Signal %d received\n", __FUNCTION__, signal_number); - _as_simulator_ue_is_running = FALSE; - _as_simulator_mme_is_running = FALSE; + _as_simulator_ue_is_running = false; + _as_simulator_mme_is_running = false; } /* @@ -321,7 +321,7 @@ static void* _as_simulator_ue_mngr(void* args) int msg_id; as_message_t msg; - _as_simulator_ue_is_running = TRUE; + _as_simulator_ue_is_running = true; printf("INFO\t: %s - UE connection manager started\n", __FUNCTION__); @@ -388,7 +388,7 @@ static void* _as_simulator_ue_mngr(void* args) } /* Close the connection to the network sublayer */ - _as_simulator_ue_is_running = FALSE; + _as_simulator_ue_is_running = false; printf("ERROR\t: The UE connection manager exited\n"); return (NULL); } @@ -403,7 +403,7 @@ static void* _as_simulator_mme_mngr(void* args) int msg_id; as_message_t msg; - _as_simulator_mme_is_running = TRUE; + _as_simulator_mme_is_running = true; printf("INFO\t: %s - MME connection manager started\n", __FUNCTION__); @@ -469,7 +469,7 @@ static void* _as_simulator_mme_mngr(void* args) } /* Close the connection to the network sublayer */ - _as_simulator_mme_is_running = FALSE; + _as_simulator_mme_is_running = false; printf("ERROR\t: %s - The MME connection manager exited\n", __FUNCTION__); return (NULL); } diff --git a/openair3/NAS/TEST/NETWORK/network_simulator.c b/openair3/NAS/TEST/NETWORK/network_simulator.c index 461f701f95..492a709463 100644 --- a/openair3/NAS/TEST/NETWORK/network_simulator.c +++ b/openair3/NAS/TEST/NETWORK/network_simulator.c @@ -208,7 +208,7 @@ static const OctetString* _network_simulator_pdn[NETWORK_IP_MAX][2] = { static int _set_signal_handler(int signal, void (handler)(int)); static void _signal_handler(int signal_number); static int _process_message(int msgID, const as_message_t* req); -static int _assign_pdn_address(int ue_pdn_type, int is_initial, int* pdn_type, OctetString* pdn); +static int _assign_pdn_address(int ue_pdn_type, bool is_initial, int* pdn_type, OctetString* pdn); /* Functions used to process messages received from the Access Stratum */ static int _process_cell_info_req(const cell_info_req_t* req, cell_info_cnf_t* rsp); @@ -283,7 +283,7 @@ int main (int argc, const char* argv[]) /* * Network simulator main loop */ - while (TRUE) { + while (true) { as_message_t msg; /* Receive message from the NAS */ @@ -1072,11 +1072,11 @@ static int _process_pdn_connectivity_request(const pdn_connectivity_request_msg* /* Assign PDN address */ if (apn.length > 0) { request->accesspointname.accesspointnamevalue = apn; - esm_cause = _assign_pdn_address(requested_pdn_type, FALSE, &pdn_type, + esm_cause = _assign_pdn_address(requested_pdn_type, false, &pdn_type, &request->pdnaddress.pdnaddressinformation); } else { request->accesspointname.accesspointnamevalue = EURECOM_APN; - esm_cause = _assign_pdn_address(requested_pdn_type, TRUE, &pdn_type, + esm_cause = _assign_pdn_address(requested_pdn_type, true, &pdn_type, &request->pdnaddress.pdnaddressinformation); } diff --git a/openair3/NAS/TEST/USER/user_simulator.c b/openair3/NAS/TEST/USER/user_simulator.c index 1c429c3b85..3050c16692 100644 --- a/openair3/NAS/TEST/USER/user_simulator.c +++ b/openair3/NAS/TEST/USER/user_simulator.c @@ -192,7 +192,7 @@ int main (int argc, const char* argv[]) /* * User simulator main loop */ - while (TRUE) { + while (true) { char c; int len; @@ -293,7 +293,7 @@ static void _signal_handler(int signal_number) */ static void* _receive_thread(void* arg) { - while (TRUE) { + while (true) { /* Receive AT response from the NAS sublayer */ int rbytes = USER_RECV(_user_simulator_recv_buffer, USER_SIMULATOR_BUFFER_SIZE); diff --git a/openair3/NAS/UE/API/USER/at_command.c b/openair3/NAS/UE/API/USER/at_command.c index ab85b2d2fa..a6591c6748 100644 --- a/openair3/NAS/UE/API/USER/at_command.c +++ b/openair3/NAS/UE/API/USER/at_command.c @@ -354,7 +354,7 @@ static int ParseString(char * at_str, at_command_t* at_command) char* terminal_character_index = NULL; int num_of_chars_to_compare = -1; int handler_index; - int handler_found = FALSE; + bool handler_found = false; int check_for_carriage_return_index = 0; /* @@ -415,7 +415,7 @@ static int ParseString(char * at_str, at_command_t* at_command) if (strncasecmp(at_str, _at_command_handler[handler_index].command, num_of_chars_to_compare) != 0) continue; - handler_found = TRUE; + handler_found = true; break; } @@ -681,7 +681,7 @@ static unsigned int NumberOfParameters(const unsigned char* str) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ @@ -689,11 +689,11 @@ static unsigned int IsNumeric(const char* str, size_t len) { while (len-- > 0) { if (!isdigit(str[len])) { - return FALSE; + return false; } } - return TRUE; + return true; } /****************************************************************************/ @@ -719,7 +719,7 @@ static int parse_e1(const char* string, int position, at_command_t* at_command) static int parse_q0(const char* string, int position, at_command_t* at_command) { /* Result code suppression Q0 */ - at_error_code_suppression_q1 = FALSE; + at_error_code_suppression_q1 = false; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -728,7 +728,7 @@ static int parse_q0(const char* string, int position, at_command_t* at_command) static int parse_q1(const char* string, int position, at_command_t* at_command) { /* Result code suppression Q1 */ - at_error_code_suppression_q1 = TRUE; + at_error_code_suppression_q1 = true; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -738,7 +738,7 @@ static int parse_v0(const char* string, int position, at_command_t* at_command) { /* Response format V0 (numeric result code + limited header) */ at_error_format = AT_ERROR_NUMERIC; - at_response_format_v1 = FALSE; + at_response_format_v1 = false; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -748,7 +748,7 @@ static int parse_v1(const char* string, int position, at_command_t* at_command) { /* Response format V1 (verbose result code + full header) */ at_error_format = AT_ERROR_VERBOSE; - at_response_format_v1 = TRUE; + at_response_format_v1 = true; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; diff --git a/openair3/NAS/UE/API/USER/at_error.c b/openair3/NAS/UE/API/USER/at_error.c index d004c89736..bad7127adc 100644 --- a/openair3/NAS/UE/API/USER/at_error.c +++ b/openair3/NAS/UE/API/USER/at_error.c @@ -55,10 +55,10 @@ extern int at_response_format_v1; /* * Result code suppression indicator (set by ATQ0 and ATQ1) * ------------------------------------------------------- - * FALSE - Result codes are transmitted to the user application - * TRUE - Result codes are suppressed and not transmitted + * false - Result codes are transmitted to the user application + * true - Result codes are suppressed and not transmitted */ -int at_error_code_suppression_q1 = FALSE; +bool at_error_code_suppression_q1 = false; /* * Verbose mode indicator (set by ATV0, ATV1 and AT+CMEE) diff --git a/openair3/NAS/UE/API/USER/at_response.c b/openair3/NAS/UE/API/USER/at_response.c index 859db90d7e..eef0385750 100644 --- a/openair3/NAS/UE/API/USER/at_response.c +++ b/openair3/NAS/UE/API/USER/at_response.c @@ -52,10 +52,10 @@ Description Defines structure of the AT command response returned after /* * Response format indicator (set by ATV0 and ATV1) * ----------------------------------------------- - * TRUE - , - * FALSE - , + * true - , + * false - , */ -int at_response_format_v1 = TRUE; +bool at_response_format_v1 = true; /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 5e7a1f578b..52f7ebce44 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -146,7 +146,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) /* Update the emergency bearer service indicator */ if (type == EMM_ATTACH_TYPE_EMERGENCY) { - user->emm_data->is_emergency = TRUE; + user->emm_data->is_emergency = true; } /* Setup initial NAS information message to transfer */ @@ -211,7 +211,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) } /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, FALSE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, false); emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE; if (user->emm_data->security) { @@ -230,8 +230,8 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) * is requested to setup a default EPS bearer */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = FALSE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = false; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = 1; /* TODO: PDN type should be set according to the IP capability of the UE */ esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4; @@ -387,7 +387,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, if (n_eplmns > 0) { for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { - int is_forbidden = FALSE; + bool is_forbidden = false; if (!user->emm_data->is_emergency) { /* If the attach procedure is not for emergency bearer @@ -395,7 +395,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, * code that is already in the list of forbidden PLMNs */ for (j = 0; j < user->emm_data->fplmn.n_plmns; j++) { if (PLMNS_ARE_EQUAL(eplmn[i], user->emm_data->fplmn.plmn[j])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -418,7 +418,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, * Notify ESM that a default EPS bearer has to be activated */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = esm_msg_pP; rc = esm_sap_send(user, &esm_sap); @@ -445,7 +445,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, emm_sap.u.emm_as.u.data.ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); /* Get the activate default EPS bearer context accept message * to be transfered within the ESM container of the attach * complete message */ @@ -546,7 +546,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_EPS_NOT_ALLOWED: case EMM_CAUSE_BOTH_NOT_ALLOWED: /* Consider the USIM as invalid for EPS services */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* Delete the list of equivalent PLMNs */ user->emm_data->nvdata.eplmn.n_plmns = 0; break; @@ -682,7 +682,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e if (esm_msg_pP != NULL) { esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = esm_msg_pP; rc = esm_sap_send(user, &esm_sap); } @@ -731,7 +731,7 @@ int emm_proc_attach_complete(void *args) /* Set the EPS update status to EU1 UPDATED */ user->emm_data->status = EU1_UPDATED; - user->emm_data->is_attached = TRUE; + user->emm_data->is_attached = true; /* * Notify EMM that network attach complete message has been delivered @@ -747,7 +747,7 @@ int emm_proc_attach_complete(void *args) * Complete message */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; rc = esm_sap_send(user, &esm_sap); } @@ -766,7 +766,7 @@ int emm_proc_attach_complete(void *args) ** The UE shall restart the attach procedure when timer ** ** T3411 expires. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** Inputs: is_initial: true if the NAS message that failed to be ** ** transfered is an initial NAS message (ESM ** ** message embedded within an Attach Request ** ** message) ** @@ -778,7 +778,7 @@ int emm_proc_attach_complete(void *args) ** Others: T3410, T3411 ** ** ** ***************************************************************************/ -int emm_proc_attach_failure(int is_initial, void *args) +int emm_proc_attach_failure(bool is_initial, void *args) { LOG_FUNC_IN; int rc = RETURNok; @@ -804,7 +804,7 @@ int emm_proc_attach_failure(int is_initial, void *args) * to be transmitted */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = NULL; } else { /* @@ -813,7 +813,7 @@ int emm_proc_attach_failure(int is_initial, void *args) * has failed to be transmitted */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = NULL; } @@ -919,7 +919,7 @@ int emm_proc_attach_set_emergency(emm_data_t *emm_data) LOG_TRACE(WARNING, "EMM-PROC - UE is now attached to the network for " "emergency bearer services only"); - emm_data->is_emergency = TRUE; + emm_data->is_emergency = true; LOG_FUNC_RETURN(RETURNok); } @@ -950,7 +950,7 @@ int emm_proc_attach_set_detach(void *nas_user) "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ - user->emm_data->is_attached = FALSE; + user->emm_data->is_attached = false; /* * Notify that the UE is locally detached from the network */ diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index a2762d08e8..a3b58f89f4 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -129,7 +129,7 @@ static int _authentication_kasme(const OctetString *autn, ** authentication challenge data and respond with an AUTHEN- ** ** TICATION RESPONSE message to the network. ** ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** + ** Inputs: native_ksi: true if the security context is of type ** ** native (for KSIASME) ** ** ksi: The NAS ket sey identifier ** ** rand: Authentication parameter RAND ** @@ -179,14 +179,14 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, OctetString res = {AUTH_RES_SIZE, authentication_data->res}; if ((memcmp(authentication_data->rand, rand->value, AUTH_CK_SIZE) != 0) || - (authentication_data->auth_process_started == FALSE)) { + (authentication_data->auth_process_started == false)) { /* * There is no valid stored RAND in the ME or the stored RAND is * different from the new received value in the AUTHENTICATION * REQUEST message OR if this is first time UE starting the * Authentication process */ - authentication_data->auth_process_started = TRUE; + authentication_data->auth_process_started = true; OctetString auts; auts.length = 0; auts.value = (uint8_t *)malloc(AUTH_AUTS_SIZE); @@ -308,7 +308,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, emm_sap.u.emm_as.u.security.res = &res; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { @@ -398,7 +398,7 @@ int emm_proc_authentication_reject(nas_user_t *user) } /* Consider the USIM invalid */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* Stop timer T3410 */ if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { @@ -652,7 +652,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, emm_sap.u.emm_as.u.security.auts = auts; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index b61bcdc14d..654486226e 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -114,7 +114,7 @@ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type); ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off) +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, bool switch_off) { LOG_FUNC_IN; @@ -154,7 +154,7 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of emm_as->guti = user->emm_data->guti; emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, true); /* * Notify EMM-AS SAP that Detach Request message has to @@ -280,7 +280,7 @@ int emm_proc_detach_accept(void* args) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_detach_failure(int is_initial, void *args) +int emm_proc_detach_failure(bool is_initial, void *args) { LOG_FUNC_IN; @@ -405,8 +405,7 @@ void *emm_detach_t3421_handler(void *args) emm_as->guti = user->emm_data->guti; emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, - FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, true); /* * Notify EMM-AS SAP that Detach Request message has to diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index 367d0327f4..9ac2fc794b 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -137,8 +137,7 @@ int emm_proc_status(nas_user_t *user, int emm_cause) emm_sap.u.emm_as.u.status.guti = user->emm_data->guti; sctx = user->emm_data->security; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, - FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, false, true); rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index 0364c6d22f..d4fc85a931 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -199,8 +199,7 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index 362d5e5b4a..50a318355c 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -663,8 +663,8 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) ** to camp on an acceptable cell, irrespective of its PLMN ** ** identity, so that only emergency calls can be made. ** ** ** - ** Inputs: found: TRUE if a suitable cell of the chosen ** - ** PLMN has been found; FALSE otherwise. ** + ** Inputs: found: true if a suitable cell of the chosen ** + ** PLMN has been found; false otherwise. ** ** tac: The code of the location/tracking area the ** ** chosen PLMN belongs to ** ** ci: The identifier of the cell ** @@ -685,7 +685,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; user_api_id_t *user_api_id = user->user_api_id; int index = emm_plmn_list->index; - int select_next_plmn = FALSE; + bool select_next_plmn = false; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, @@ -694,7 +694,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, "Automatic/manual"); if (found) { - int is_forbidden = FALSE; + bool is_forbidden = false; /* Select the PLMN of which a suitable cell has been found */ emm_data->splmn = *emm_plmn_list->plmn[index]; @@ -721,7 +721,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, /* Check if the selected PLMN is in the forbidden list */ for (i = 0; i < emm_data->fplmn.n_plmns; i++) { if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -730,7 +730,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) { if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn_gprs.plmn[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -745,7 +745,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (!is_forbidden) { for (i = 0; i < emm_data->ftai.n_tais; i++) { if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -754,7 +754,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (!is_forbidden) { for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) { if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -793,7 +793,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Try to select the next PLMN in the ordered list of available PLMNs */ index += 1; - select_next_plmn = TRUE; + select_next_plmn = true; /* Bypass the previously selected PLMN */ if (index == emm_plmn_list->splmn) { @@ -809,7 +809,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * registered or equivalent PLMNs is ongoing */ index += 1; - select_next_plmn = TRUE; + select_next_plmn = true; } else if (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { @@ -830,7 +830,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, */ emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; index = emm_plmn_list->hplmn; - select_next_plmn = TRUE; + select_next_plmn = true; } /* @@ -851,7 +851,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } else { /* No suitable cell of any PLMN within the ordered list * of available PLMNs has been found */ - select_next_plmn = FALSE; + select_next_plmn = false; emm_sap.primitive = EMMREG_NO_CELL; } } @@ -892,11 +892,11 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (emm_plmn_list->splmn == emm_plmn_list->rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - emm_data->is_rplmn = TRUE; + emm_data->is_rplmn = true; } else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - emm_data->is_eplmn = TRUE; + emm_data->is_eplmn = true; } /* diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index 01b07fc356..538ba21099 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -208,7 +208,7 @@ int lowerlayer_data_ind(nas_user_t *user, const OctetString *data) LOG_FUNC_IN; esm_sap.primitive = ESM_UNITDATA_IND; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.ueid = user->ueid; esm_sap.recv = data; @@ -250,7 +250,7 @@ int lowerlayer_data_req(nas_user_t *user, const OctetString *data) emm_sap.u.emm_as.u.data.NASmsg.length = data->length; emm_sap.u.emm_as.u.data.NASmsg.value = data->value; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, false, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); @@ -336,7 +336,7 @@ int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) ** Description: Handles EMM procedure to be executed upon receiving noti- ** ** fication that data failed to be delivered to the network. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** Inputs: is_initial: true if the NAS message that failed to be ** ** transfered is an initial NAS message ** ** Others: None ** ** ** @@ -345,7 +345,7 @@ int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial) +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, bool is_initial) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 0d8eefc7f3..ed60e379bc 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -72,7 +72,7 @@ int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlaye lowerlayer_release_callback_t release, void *args); int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data); -int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial); +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, bool is_initial); int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data); diff --git a/openair3/NAS/UE/EMM/LowerLayer_defs.h b/openair3/NAS/UE/EMM/LowerLayer_defs.h index 6035d4ed12..1a0ae7d656 100644 --- a/openair3/NAS/UE/EMM/LowerLayer_defs.h +++ b/openair3/NAS/UE/EMM/LowerLayer_defs.h @@ -11,7 +11,7 @@ typedef int (*lowerlayer_success_callback_t)(void *); * Type of EMM procedure callback function executed when data are not * delivered to the network because a lower layer failure occurred */ -typedef int (*lowerlayer_failure_callback_t)(int, void *); +typedef int (*lowerlayer_failure_callback_t)(bool, void *); /* * Type of EMM procedure callback function executed when NAS signalling diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index f58cf4b9e0..3fa47094c7 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -120,7 +120,7 @@ int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) /* * Data failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 4310f963cd..c0763009b8 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -133,7 +133,7 @@ int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, true); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index f77c2921a3..0925cb4e0f 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -141,7 +141,7 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, true); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index fbd3e1ce63..2cd25f77d6 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -143,7 +143,7 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) /* * Data transfer message failed to be delivered */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 36929fc4d7..a770e08bab 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -240,7 +240,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index ea4eefadeb..de6dee4a5e 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -679,7 +679,7 @@ static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg int AcT = NET_ACCESS_EUTRAN; - if (msg->found == TRUE) { + if (msg->found == true) { /* Get the first supported access technology */ while (AcT != NET_ACCESS_UNAVAILABLE) { if (msg->rat & (1 << AcT)) { @@ -1081,7 +1081,7 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg LOG_FUNC_IN; ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned; int size = 0; - int is_encoded = FALSE; + bool is_encoded = false; LOG_TRACE(INFO, "EMMAS-SAP - Send AS data transfer request"); @@ -1114,7 +1114,7 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg default: /* Send other NAS messages as already encoded ESM messages */ size = msg->NASmsg.length; - is_encoded = TRUE; + is_encoded = true; break; } diff --git a/openair3/NAS/UE/EMM/SAP/emm_asDef.h b/openair3/NAS/UE/EMM/SAP/emm_asDef.h index 7bd464ec04..4f6182a2c9 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_asDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_asDef.h @@ -150,7 +150,7 @@ typedef struct emm_as_establish_s { uint32_t ueid; /* UE lower layer identifier */ emm_as_EPS_identity_t UEid; /* UE's EPS mobile identity */ emm_as_security_data_t sctx;/* EPS NAS security context */ - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ uint8_t type; /* Network attach/detach type */ uint8_t RRCcause; /* Connection establishment cause */ uint8_t RRCtype; /* Associated call type */ @@ -194,7 +194,7 @@ typedef struct emm_as_data_s { uint32_t ueid; /* UE lower layer identifier */ const GUTI_t *guti; /* GUTI temporary mobile identity */ emm_as_security_data_t sctx;/* EPS NAS security context */ - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ uint8_t type; /* Network detach type */ uint8_t delivered; /* Data message delivery indicator */ #define EMM_AS_NAS_DATA_ATTACH 0x01 /* Attach complete */ diff --git a/openair3/NAS/UE/EMM/SAP/emm_esmDef.h b/openair3/NAS/UE/EMM/SAP/emm_esmDef.h index aac37b46bf..6e7065f913 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esmDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_esmDef.h @@ -71,9 +71,9 @@ typedef enum { * --------------------------------------------- */ typedef struct { - int is_emergency; /* Indicates whether the PDN connection is established + bool is_emergency; /* Indicates whether the PDN connection is established * for emergency bearer services only */ - int is_attached; /* Indicates whether the UE remains attached to the + bool is_attached; /* Indicates whether the UE remains attached to the * network */ } emm_esm_establish_t; diff --git a/openair3/NAS/UE/EMM/SAP/emm_regDef.h b/openair3/NAS/UE/EMM/SAP/emm_regDef.h index b66c0565ea..752f328375 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_regDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_regDef.h @@ -100,7 +100,7 @@ typedef struct { * ------------------------------------- */ typedef struct { - int is_emergency; /* TRUE if the UE was attempting to register to + bool is_emergency; /* true if the UE was attempting to register to * the network for emergency services only */ } emm_reg_attach_t; @@ -109,7 +109,7 @@ typedef struct { * ------------------------------------- */ typedef struct { - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ int type; /* Network detach type */ } emm_reg_detach_t; diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index f9a02b1a70..fd3332669b 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -124,7 +124,7 @@ static void _security_release(emm_security_context_t *ctx); ** grity algorithm and ciphered with the selected NAS ciphe- ** ** ring algorithm. ** ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** + ** Inputs: native_ksi: true if the security context is of type ** ** native (for KSIASME) ** ** ksi: The NAS ket sey identifier ** ** seea: Selected EPS cyphering algorithm ** @@ -145,7 +145,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; int emm_cause = EMM_CAUSE_SUCCESS; - int security_context_is_new = FALSE; + int security_context_is_new = false; security_data_t *security_data = user->security_data; LOG_TRACE(INFO, "EMM-PROC - Security mode control requested (ksi=%d)", @@ -263,7 +263,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, user->emm_data->security->ul_count.overflow = 0; user->emm_data->security->ul_count.seq_num = 0; /* Set new security context indicator */ - security_context_is_new = TRUE; + security_context_is_new = true; } } @@ -328,7 +328,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, emm_sap.u.emm_as.u.security.emm_cause = emm_cause; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, security_context_is_new, TRUE); + user->emm_data->security, security_context_is_new, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index dfdfb34e77..50219b7883 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -112,7 +112,7 @@ typedef struct { #define EMM_DETACH_COUNTER_MAX 5 unsigned int count; /* Counter used to limit the number of * subsequently detach attempts */ - int switch_off; /* UE switch-off indicator */ + bool switch_off; /* UE switch-off indicator */ emm_proc_detach_type_t type; /* Type of the detach procedure * currently in progress */ } emm_detach_data_t; @@ -249,8 +249,8 @@ typedef struct emm_data_s { emm_eps_update_t status; /* The current EPS update status */ emm_ecm_state_t ecm_status; /* The EPS Connection Management status */ - int is_attached; /* Network attachment indicator */ - int is_emergency; /* Emergency bearer services indicator*/ + bool is_attached; /* Network attachment indicator */ + bool is_emergency; /* Emergency bearer services indicator*/ /* Tracking Areas list the UE is registered to * Contains the list of TAIs that identify the tracking areas that diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 329b59fae6..74676c8b36 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -113,7 +113,7 @@ void _emm_attach_initialize(emm_attach_data_t *emm_attach_data) { void _emm_detach_initialize(emm_detach_data_t *emm_detach) { emm_detach->count = 0; - emm_detach->switch_off = FALSE; + emm_detach->switch_off = false; emm_detach->type = EMM_DETACH_TYPE_RESERVED; } @@ -137,7 +137,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c LOG_FUNC_IN; user->emm_data = calloc_or_fail(sizeof(emm_data_t)); /* USIM validity indicator */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* The IMEI read from the UE's non-volatile memory */ user->emm_data->imei = (imei_t *)malloc(sizeof(imei_t)); user->emm_data->imei->length = _emm_main_get_imei(user->emm_data->imei, imei); @@ -157,14 +157,14 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->plmn_rat = NET_ACCESS_UNAVAILABLE; /* Selected PLMN */ memset(&user->emm_data->splmn, 0xFF, sizeof(plmn_t)); - user->emm_data->is_rplmn = FALSE; - user->emm_data->is_eplmn = FALSE; + user->emm_data->is_rplmn = false; + user->emm_data->is_eplmn = false; /* Radio Access Technology of the serving cell */ user->emm_data->rat = NET_ACCESS_UNAVAILABLE; /* Network registration status */ user->emm_data->stat = NET_REG_STATE_OFF; - user->emm_data->is_attached = FALSE; - user->emm_data->is_emergency = FALSE; + user->emm_data->is_attached = false; + user->emm_data->is_emergency = false; /* Location/Tracking area code */ user->emm_data->tac = 0; // two byte in hexadecimal format /* Identifier of the serving cell */ @@ -201,7 +201,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* The USIM application is present and valid */ LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); - user->emm_data->usim_is_valid = TRUE; + user->emm_data->usim_is_valid = true; /* print keys (for debugging) */ { @@ -844,12 +844,12 @@ AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data) ** Others: user->emm_data-> ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached to ** - ** the network; FALSE otherwise. ** + ** Return: true if the UE is currently attached to ** + ** the network; false otherwise. ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_attached(emm_data_t *emm_data) +bool emm_main_is_attached(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_FUNC_RETURN (emm_data->is_attached); @@ -866,13 +866,13 @@ int emm_main_is_attached(emm_data_t *emm_data) ** Others: user->emm_data-> ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached or is ** + ** Return: true if the UE is currently attached or is ** ** attempting to attach to the network for ** - ** emergency bearer services; FALSE otherwise ** + ** emergency bearer services; false otherwise ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_emergency(emm_data_t *emm_data) +bool emm_main_is_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_FUNC_RETURN (emm_data->is_attached && emm_data->is_emergency); @@ -967,8 +967,8 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE if the first IMSI is found to match ** - ** the second; FALSE otherwise. ** + ** Return: true if the first IMSI is found to match ** + ** the second; false otherwise. ** ** Others: None ** ** ** ***************************************************************************/ @@ -977,16 +977,16 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) int i; if (imsi1->length != imsi2->length) { - return FALSE; + return false; } for (i = 0; i < imsi1->length; i++) { if (imsi1->u.value[i] != imsi2->u.value[i]) { - return FALSE; + return false; } } - return TRUE; + return true; } /**************************************************************************** diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index d30f778e3b..d081024548 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -94,8 +94,8 @@ AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ -int emm_main_is_attached(emm_data_t *emm_data); -int emm_main_is_emergency(emm_data_t *emm_data); +bool emm_main_is_attached(emm_data_t *emm_data); +bool emm_main_is_emergency(emm_data_t *emm_data); #endif /* __EMM_MAIN_H__*/ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 7d4024d9d6..b93bb33bf1 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -89,7 +89,7 @@ int emm_proc_attach_accept(nas_user_t *user, long T3412, long T3402, long T3423, const OctetString *esm_msg); int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg); int emm_proc_attach_complete(void *args); -int emm_proc_attach_failure(int is_initial, void *args); +int emm_proc_attach_failure(bool is_initial, void *args); int emm_proc_attach_release(void *args); int emm_proc_attach_restart(nas_user_t *user); @@ -103,10 +103,10 @@ int emm_proc_attach_set_detach(void *user); * Detach procedure * -------------------------------------------------------------------------- */ -int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off); +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, bool switch_off); int emm_proc_detach_request(void *args); int emm_proc_detach_accept(void *args); -int emm_proc_detach_failure(int is_initial, void *args); +int emm_proc_detach_failure(bool is_initial, void *args); int emm_proc_detach_release(void *args); diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 21c3da3f19..db95dd648f 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -131,7 +131,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int } /* Assign dedicated EPS bearer context */ - int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, false); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal cases a and b @@ -141,7 +141,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested dedicated EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -149,7 +149,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new dedicated EPS bearer context */ - ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, false); } } @@ -165,7 +165,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER; } else { /* Create new dedicated EPS bearer context */ - default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, FALSE, qos, tft); + default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, false, qos, tft); if (default_ebi != ESM_EBI_UNASSIGNED) { /* Dedicated EPS bearer contextx successfully created */ @@ -197,7 +197,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int ** Inputs: is_standalone: Not used ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** @@ -206,8 +206,8 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -268,8 +268,8 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 7c528d7569..f61b149822 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -103,7 +103,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e "requested by the network (ebi=%d)", ebi); /* Assign default EPS bearer context */ - int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, true); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.1.5, abnormal cases a and b @@ -113,7 +113,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested default EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -121,13 +121,13 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new default EPS bearer context */ - ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, true); } } if (ebi != ESM_EBI_UNASSIGNED) { /* Create new default EPS bearer context */ - ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, TRUE, qos, NULL); + ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, true, qos, NULL); if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ @@ -165,9 +165,9 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e ** te message ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE (should be always ** - ** TRUE) ** + ** true) ** ** Others: None ** ** ** ** Outputs: None ** @@ -175,8 +175,8 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -245,8 +245,8 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -344,7 +344,7 @@ int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) "ESM-PROC - Default EPS bearer context activation failure"); /* Release the default EPS bearer context and enter state INACTIVE */ - int rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &pid, &bid); + int rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &pid, &bid); if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 5adbae05c6..742e70cd4a 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -97,7 +97,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); ** has an EPS bearer context with specified EPS bearer iden- ** ** tity activated. ** ** ** - ** Inputs: is local: TRUE if the EPS bearer context has to be ** + ** Inputs: is local: true if the EPS bearer context has to be ** ** locally released without peer-to-peer si- ** ** gnalling between the UE and the MME ** ** ebi: EPS bearer identity of the EPS bearer con- ** @@ -111,7 +111,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, bool is_local, int ebi, int *pid, int *bid) { LOG_FUNC_IN; @@ -213,7 +213,7 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in * the PDN connection */ if (*esm_cause == ESM_CAUSE_REACTIVATION_REQUESTED) { esm_sap_t esm_sap; - int active = FALSE; + bool active = false; /* 3GPP TS 24.301, section 6.4.4.3 * The UE should re-initiate the UE requested PDN connectivity @@ -242,8 +242,8 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in * Notify ESM to re-initiate PDN connectivity procedure */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = pid + 1; rc = esm_sap_send(user, &esm_sap); } @@ -265,10 +265,10 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in ** DEACTIVATE EPS BEARER CONTEXT ACCEPT message and entering ** ** the state BEARER CONTEXT INACTIVE. ** ** ** - ** Inputs: is_standalone: Should be always TRUE ** + ** Inputs: is_standalone: Should be always true ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** @@ -277,8 +277,8 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -371,7 +371,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); } else { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, false); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ diff --git a/openair3/NAS/UE/ESM/EsmStatusHdl.c b/openair3/NAS/UE/ESM/EsmStatusHdl.c index def498a89b..88f6550251 100644 --- a/openair3/NAS/UE/ESM/EsmStatusHdl.c +++ b/openair3/NAS/UE/ESM/EsmStatusHdl.c @@ -149,7 +149,7 @@ int esm_proc_status_ind( ** ** ** Description: Initiates ESM status procedure. ** ** ** - ** Inputs: is_standalone: Not used - Always TRUE ** + ** Inputs: is_standalone: Not used - Always true ** ** ueid: UE lower layer identifier ** ** ebi: Not used ** ** msg: Encoded ESM status message to be sent ** @@ -161,9 +161,9 @@ int esm_proc_status_ind( ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_status(nas_user_t *user, int is_standalone, +int esm_proc_status(nas_user_t *user, bool is_standalone, int ebi, OctetString *msg, - int ue_triggered) + bool ue_triggered) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index d17b5fde3c..a79320cccb 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -80,7 +80,7 @@ Description Defines the PDN connectivity ESM procedure executed by the * PDN connection handlers */ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, - esm_proc_pdn_type_t pdn_type, int is_emergency); + esm_proc_pdn_type_t pdn_type, bool is_emergency); static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause); static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid); @@ -121,7 +121,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ** to be defined or undefined ** ** pdn_type: PDN connection type (IPv4, IPv6, IPv4v6) ** ** apn: Access Point logical Name to be used ** - ** is_emergency: TRUE if the PDN connection has to be esta- ** + ** is_emergency: true if the PDN connection has to be esta- ** ** blished for emergency bearer services ** ** Others: None ** ** ** @@ -133,7 +133,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ***************************************************************************/ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, esm_proc_pdn_type_t pdn_type, - const OctetString *apn, int is_emergency, + const OctetString *apn, bool is_emergency, unsigned int *pti) { LOG_FUNC_IN; @@ -270,7 +270,7 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, ** pti: Procedure transaction identity ** ** msg: Encoded PDN connectivity request message ** ** to be sent ** - ** sent_by_ue: Not used - Always TRUE ** + ** sent_by_ue: Not used - Always true ** ** Others: None ** ** ** ** Outputs: None ** @@ -278,8 +278,8 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue) +int esm_proc_pdn_connectivity_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue) { LOG_FUNC_IN; esm_pt_data_t *esm_pt_data = user->esm_pt_data; @@ -523,7 +523,7 @@ int esm_proc_pdn_connectivity_complete(nas_user_t *user) ** PDN connectivity procedure which is still pending in the ** ** PROCEDURE TRANSACTION INACTIVE or PENDING state. ** ** ** - ** Inputs: is_pending: TRUE if this PDN connectivity procedure ** + ** Inputs: is_pending: true if this PDN connectivity procedure ** ** transaction is in the PENDING state ** ** Others: None ** ** ** @@ -679,7 +679,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) ** Inputs: pid: Identifier of the PDN connection entry ** ** apn: Access Point Name of the PDN connection ** ** pdn_type: PDN type (IPv4, IPv6, IPv4v6) ** - ** is_emergency: TRUE if the PDN connection has to be esta- ** + ** is_emergency: true if the PDN connection has to be esta- ** ** blished for emergency bearer services ** ** ** ** Outputs: None ** @@ -688,7 +688,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) ***************************************************************************/ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, - int is_emergency) + bool is_emergency) { esm_pdn_t *pdn = NULL; @@ -720,7 +720,7 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt /* Set the PDN connection identifier */ esm_data->pdn[pid].pid = pid; /* Reset the PDN connection active indicator */ - esm_data->pdn[pid].is_active = FALSE; + esm_data->pdn[pid].is_active = false; /* Setup the PDN connection data */ esm_data->pdn[pid].data = pdn; } @@ -744,7 +744,7 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt } pdn->type = pdn_type; - pdn->addr_realloc = FALSE; + pdn->addr_realloc = false; return (RETURNok); } @@ -825,7 +825,7 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt * the other IP version using the UE requested PDN connectivity * procedure to the same APN with a single address PDN type * (IPv4 or IPv6) other than the one already activated */ - pdn->addr_realloc = TRUE; + pdn->addr_realloc = true; } else if ( (esm_cause == ESM_CAUSE_PDN_TYPE_IPV4_ONLY_ALLOWED) || (esm_cause == ESM_CAUSE_PDN_TYPE_IPV6_ONLY_ALLOWED) ) { /* The UE requested IPv4 or IPv6 address and the network allows @@ -833,9 +833,9 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt * The UE shall not subsequently initiate another UE requested * PDN connectivity procedure to the same APN to obtain a PDN * type different from the one allowed by the network */ - pdn->addr_realloc = FALSE; + pdn->addr_realloc = false; } else if (pdn_type != ESM_PDN_TYPE_IPV4V6) { - pdn->addr_realloc = TRUE; + pdn->addr_realloc = true; } return (RETURNok); diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 6665126e40..cb7b3225bc 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -155,7 +155,7 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un ** PDN DISCONNECT REQUEST message to the MME, starting timer ** ** T3492 and entering state PROCEDURE TRANSACTION PENDING. ** ** ** - ** Inputs: is_standalone: Should be always TRUE ** + ** Inputs: is_standalone: Should be always true ** ** pti: Procedure transaction identity ** ** msg: Encoded PDN disconnect request message to ** ** be sent ** @@ -167,8 +167,8 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue) +int esm_proc_pdn_disconnect_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue) { LOG_FUNC_IN; @@ -326,7 +326,7 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) */ esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; @@ -444,7 +444,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) */ esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index e039f66a3a..f1663175d4 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -63,9 +63,9 @@ Description Defines the ESM Service Access Points at which the EPS /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, bool is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err); -static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, +static int _esm_sap_send(nas_user_t *user, int msg_type, bool is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp); @@ -171,7 +171,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) } /* Define new PDN context */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, true, pdn_connect->pdn_type, &apn, pdn_connect->is_emergency, NULL); @@ -183,7 +183,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if (pdn_connect->is_defined) { unsigned int pti; /* Assign new procedure transaction identity */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, true, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, &pti); @@ -205,7 +205,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if ( msg->is_standalone && pdn_connect->is_defined ) { /* Undefine the specified PDN context */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, FALSE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, false, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { @@ -214,7 +214,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) msg->recv, &msg->send, &msg->err); } else { /* The PDN connectivity procedure locally failed */ - rc = esm_proc_pdn_connectivity_failure(user, TRUE); + rc = esm_proc_pdn_connectivity_failure(user, true); } } break; @@ -230,7 +230,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if (rc != RETURNerror) { /* Send PDN disconnect request */ - rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, + rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, true, pti, ebi, &msg->data, &msg->send); } } @@ -278,7 +278,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) rc = esm_proc_default_eps_bearer_context_failure(user); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_failure(user, FALSE); + rc = esm_proc_pdn_connectivity_failure(user, false); } break; @@ -306,7 +306,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) /* * Locally deactivate EPS bearer context */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, + rc = esm_proc_eps_bearer_context_deactivate(user, true, msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid); } break; @@ -359,7 +359,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, bool is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err) { @@ -422,7 +422,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * was triggered network-internally */ int triggered_by_ue = (pti != PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); /* Indicate whether the received message shall be ignored */ - int is_discarded = FALSE; + bool is_discarded = false; if (esm_cause != ESM_CAUSE_SUCCESS) { LOG_TRACE(ERROR, "ESM-SAP - Failed to decode expected ESM message " @@ -455,7 +455,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * of already accepted activate default EPS bearer context * request message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* Return reject message */ @@ -493,7 +493,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * of already accepted activate dedicated EPS bearer context * request message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* Return reject message */ @@ -525,7 +525,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * received with PTI reserved value, or assigned value * that does not match any PTI in use */ - is_discarded = TRUE; + is_discarded = true; } else if ( (esm_cause == ESM_CAUSE_SUCCESS) || (esm_cause == ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY) ) { /* Return accept message */ @@ -541,7 +541,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * message with the EPS bearer identity set to the received * EPS bearer identity */ - is_discarded = TRUE; + is_discarded = true; } } @@ -565,7 +565,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * Ignore PDN connectivity reject message received with * reserved or unassigned EPS bearer identity value */ - is_discarded = TRUE; + is_discarded = true; } break; @@ -588,7 +588,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * Ignore PDN disconnect reject message received with * reserved or unassigned EPS bearer identity value */ - is_discarded = TRUE; + is_discarded = true; } break; @@ -629,7 +629,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * onto the network */ esm_procedure = esm_proc_status; /* Discard received ESM message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* ESM message processing succeed */ @@ -687,7 +687,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_send(nas_user_t *user, int msg_type, bool is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp) { @@ -697,7 +697,7 @@ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int rc = RETURNok; /* Indicate whether the message is sent by the UE or the MME */ - int sent_by_ue = TRUE; + bool sent_by_ue = true; ESM_msg esm_msg; memset(&esm_msg, 0 , sizeof(ESM_msg)); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sapDef.h b/openair3/NAS/UE/ESM/SAP/esm_sapDef.h index 4ff7c7e9dd..2d3227ba75 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sapDef.h +++ b/openair3/NAS/UE/ESM/SAP/esm_sapDef.h @@ -109,11 +109,11 @@ typedef struct esm_activate_eps_default_bearer_context_s { */ typedef struct esm_pdn_connectivity_s { int cid; /* PDN connection local identifier */ - int is_defined; /* Indicates whether a PDN context has been defined + bool is_defined; /* Indicates whether a PDN context has been defined * for the specified APN */ int pdn_type; /* PDN address type (IPv4, IPv6, IPv4v6) */ const char *apn; /* PDN's Access Point Name */ - int is_emergency; /* Indicates whether the PDN context has been + bool is_emergency; /* Indicates whether the PDN context has been * defined to establish connection for emergency * bearer services */ } esm_pdn_connectivity_t; @@ -149,7 +149,7 @@ typedef union { typedef struct esm_sap_s { esm_primitive_t primitive; /* ESM-SAP primitive to process */ - int is_standalone; /* Indicates whether the ESM message handled + bool is_standalone; /* Indicates whether the ESM message handled * within this primitive has to be sent/received * standalone or together within an EMM related * message */ diff --git a/openair3/NAS/UE/ESM/SAP/esm_send.c b/openair3/NAS/UE/ESM/SAP/esm_send.c index 020d9d89e3..e710d745ad 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_send.c +++ b/openair3/NAS/UE/ESM/SAP/esm_send.c @@ -132,7 +132,7 @@ int esm_send_status(int pti, int ebi, esm_status_msg *msg, int esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_send_pdn_connectivity_request(int pti, int is_emergency, int pdn_type, +int esm_send_pdn_connectivity_request(int pti, bool is_emergency, int pdn_type, const char *apn, pdn_connectivity_request_msg *msg) { diff --git a/openair3/NAS/UE/ESM/SAP/esm_send.h b/openair3/NAS/UE/ESM/SAP/esm_send.h index f97454027a..b9bcab0f39 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_send.h +++ b/openair3/NAS/UE/ESM/SAP/esm_send.h @@ -40,6 +40,8 @@ Description Defines functions executed at the ESM Service Access #ifndef __ESM_SEND_H__ #define __ESM_SEND_H__ +#include + #include "EsmStatus.h" @@ -90,7 +92,7 @@ int esm_send_status(int pti, int ebi, esm_status_msg *msg, int esm_cause); * Transaction related messages * ---------------------------- */ -int esm_send_pdn_connectivity_request(int pti, int is_emergency, int pdn_type, +int esm_send_pdn_connectivity_request(int pti, bool is_emergency, int pdn_type, const char *apn, pdn_connectivity_request_msg *msg); int esm_send_pdn_disconnect_request(int pti, int ebi, pdn_disconnect_request_msg *msg); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 16f4707a37..525f4ec00a 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -37,6 +37,7 @@ Description Defines internal private data handled by EPS Session *****************************************************************************/ #include // sprintf +#include #include "networkDef.h" #include "OctetString.h" @@ -92,7 +93,7 @@ typedef enum { typedef struct esm_ebr_context_s { unsigned char ebi; /* EPS bearer identity */ esm_ebr_state status; /* EPS bearer context status */ - int is_default_ebr; /* TRUE if the bearer context is associated + bool is_default_ebr; /* bool if the bearer context is associated * to a default EPS bearer */ char cid; /* Identifier of the PDN context the EPS * bearer context has been assigned to */ @@ -137,7 +138,7 @@ typedef struct esm_bearer_s { typedef struct esm_pdn_s { unsigned int pti; /* Identity of the procedure transaction executed * to activate the PDN connection entry */ - int is_emergency; /* Emergency bearer services indicator */ + bool is_emergency; /* Emergency bearer services indicator */ OctetString apn; /* Access Point Name currently in used */ int ambr; /* Aggregate Maximum Bit Rate of this APN */ int type; /* Address PDN type (IPv4, IPv6, IPv4v6) */ @@ -147,7 +148,7 @@ typedef struct esm_pdn_s { ESM_DATA_IPV6_ADDRESS_SIZE) /* IPv4 PDN address and/or IPv6 prefix */ char ip_addr[ESM_DATA_IP_ADDRESS_SIZE+1]; - int addr_realloc; /* Indicates whether the UE is allowed to subsequently + bool addr_realloc; /* Indicates whether the UE is allowed to subsequently * request another PDN connectivity to the same APN * using an address PDN type (IPv4 or IPv6) other * than the one already activated */ @@ -175,7 +176,7 @@ typedef struct esm_data_context_s { #define ESM_DATA_PDN_MAX 4 struct { int pid; /* Identifier of the PDN connection */ - int is_active; /* TRUE/FALSE if the PDN connection is active/inactive + bool is_active; /* true/false if the PDN connection is active/inactive * or the process to activate/deactivate the PDN * connection is in progress */ esm_pdn_t *data; /* Active PDN connection data */ diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 3a62812eca..4c6b56cec9 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -153,7 +153,7 @@ void esm_ebr_register_callback(esm_indication_callback_t cb) ** ebi: Identity of the new EPS bearer context ** ** cid: Identifier of the PDN context the EPS bea- ** ** rer context is associated to ** - ** default_ebr TRUE if the new bearer context is associa- ** + ** default_ebr bool if the new bearer context is associa- ** ** ted to a default EPS bearer ** ** Others: None ** ** ** @@ -163,7 +163,7 @@ void esm_ebr_register_callback(esm_indication_callback_t cb) ** the not assigned EBI (0) otherwise. ** ** ** ***************************************************************************/ -int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr) +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, bool default_ebr) { esm_ebr_context_t *ebr_ctx = NULL; int i; @@ -284,7 +284,7 @@ int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, ** ** ** ebi: The identity of the EPS bearer ** ** status: The new EPS bearer context status ** - ** ue_requested: TRUE/FALSE if the modification of the EPS ** + ** ue_requested: true/false if the modification of the EPS ** ** bearer context status was requested by the ** ** UE/network ** ** Others: None ** @@ -294,7 +294,7 @@ int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, ** ** ***************************************************************************/ int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, - int ebi, esm_ebr_state status, int ue_requested) + int ebi, esm_ebr_state status, bool ue_requested) { esm_ebr_context_t *ebr_ctx; esm_ebr_state old_status; @@ -385,11 +385,11 @@ esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) +bool esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi != ESM_EBI_UNASSIGNED) && (ebi < ESM_EBI_MIN) ); } @@ -404,12 +404,11 @@ int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) ** ebi: The identity of the EPS bearer ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, - int ebi) +bool esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi == ESM_EBI_UNASSIGNED) || diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index 6de4a048a4..4447a227ba 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -75,15 +75,15 @@ typedef int (*esm_indication_callback_t) (user_api_id_t *user_api_id, int, netwo void esm_ebr_register_callback(esm_indication_callback_t cb); -int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); +bool esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); esm_ebr_data_t *esm_ebr_initialize(void); -int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr); +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, bool default_ebr); int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, bool ue_requested); esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); +bool esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); #endif /* __ESM_EBR_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index b801ca2ad5..ca69687abe 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -84,7 +84,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** Inputs: ** ** pid: PDN connection identifier ** ** ebi: EPS bearer identity ** - ** is_default: TRUE if the new bearer is a default EPS ** + ** is_default: true if the new bearer is a default EPS ** ** bearer context ** ** esm_qos: EPS bearer level QoS parameters ** ** tft: Traffic flow template parameters ** @@ -98,7 +98,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ***************************************************************************/ int esm_ebr_context_create( esm_data_t *esm_data, int ueid, - int pid, int ebi, int is_default, + int pid, int ebi, bool is_default, const network_qos_t *qos, const network_tft_t *tft) { int bid = 0; esm_data_context_t *esm_ctx = NULL; @@ -185,11 +185,11 @@ int esm_ebr_context_create( if (is_default) { /* Set the PDN connection activation indicator */ - esm_ctx->pdn[pid].is_active = TRUE; + esm_ctx->pdn[pid].is_active = true; /* Update the emergency bearer services indicator */ if (pdn->is_emergency) { - esm_ctx->emergency = TRUE; + esm_ctx->emergency = true; } // LG ADD TEMP @@ -383,7 +383,7 @@ int esm_ebr_context_create( ***************************************************************************/ int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid) { - int found = FALSE; + bool found = false; esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; @@ -416,7 +416,7 @@ int esm_ebr_context_release(nas_user_t *user, } /* The EPS bearer context entry is found */ - found = TRUE; + found = true; break; } } @@ -450,7 +450,7 @@ int esm_ebr_context_release(nas_user_t *user, if (pdn->bearer[*bid] != NULL) { ebi = pdn->bearer[*bid]->ebi; - found = TRUE; + found = true; } } } @@ -503,7 +503,7 @@ int esm_ebr_context_release(nas_user_t *user, /* Set the EPS bearer context state to INACTIVE */ esm_ebr_set_status(user_api_id, esm_ebr_data, pdn->bearer[i]->ebi, - ESM_EBR_INACTIVE, TRUE); + ESM_EBR_INACTIVE, true); /* Release EPS bearer data */ esm_ebr_release(esm_ebr_data, pdn->bearer[i]->ebi); // esm_ebr_release() @@ -519,11 +519,11 @@ int esm_ebr_context_release(nas_user_t *user, } /* Reset the PDN connection activation indicator */ - esm_ctx->pdn[*pid].is_active = FALSE; + esm_ctx->pdn[*pid].is_active = false; /* Update the emergency bearer services indicator */ if (pdn->is_emergency) { - esm_ctx->emergency = FALSE; + esm_ctx->emergency = false; } } @@ -534,7 +534,7 @@ int esm_ebr_context_release(nas_user_t *user, if (esm_ctx->n_ebrs == 0) { emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; - emm_sap.u.emm_esm.u.establish.is_attached = FALSE; + emm_sap.u.emm_esm.u.establish.is_attached = false; (void) emm_sap_send(user, &emm_sap); } /* 3GPP TS 24.301, section 6.4.4.3, 6.4.4.6 @@ -546,8 +546,8 @@ int esm_ebr_context_release(nas_user_t *user, else if (esm_ctx->emergency && (esm_ctx->n_ebrs == 1) ) { emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; - emm_sap.u.emm_esm.u.establish.is_attached = TRUE; - emm_sap.u.emm_esm.u.establish.is_emergency = TRUE; + emm_sap.u.emm_esm.u.establish.is_attached = true; + emm_sap.u.emm_esm.u.establish.is_emergency = true; (void) emm_sap_send(user, &emm_sap); } diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index d7dfb1da70..c72f3f0e8b 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -66,7 +66,7 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, +int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, bool is_default, const network_qos_t *qos, const network_tft_t *tft); int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid); diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 288e748679..895e463726 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -96,12 +96,12 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) { esm_data->pdn[i].pid = -1; - esm_data->pdn[i].is_active = FALSE; + esm_data->pdn[i].is_active = false; esm_data->pdn[i].data = NULL; } /* Emergency bearer services indicator */ - esm_data->emergency = FALSE; + esm_data->emergency = false; /* Initialize the procedure transaction identity manager */ @@ -225,12 +225,12 @@ int esm_main_get_nb_pdns(esm_data_t *esm_data) ** Inputs: None ** ** ** ** Outputs: None ** - ** Return: TRUE if a PDN connection for emergency ** + ** Return: true if a PDN connection for emergency ** ** bearer services is established ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_has_emergency(esm_data_t *esm_data) +bool esm_main_has_emergency(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -245,16 +245,16 @@ int esm_main_has_emergency(esm_data_t *esm_data) ** ** ** Inputs: cid: PDN connection identifier ** ** ** - ** Outputs: state: TRUE if the current state of the PDN con- ** - ** nection is ACTIVE; FALSE otherwise. ** - ** Return: TRUE if the specified PDN connection has a ** - ** PDN context defined; FALSE if no any PDN ** + ** Outputs: state: true if the current state of the PDN con- ** + ** nection is ACTIVE; false otherwise. ** + ** Return: true if the specified PDN connection has a ** + ** PDN context defined; false if no any PDN ** ** context has been defined for the specified ** ** connection. ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) +bool esm_main_get_pdn_status(nas_user_t *user, int cid, bool *state) { LOG_FUNC_IN; @@ -263,14 +263,14 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) esm_ebr_data_t *esm_ebr_data = user-> esm_ebr_data; if (pid >= ESM_DATA_PDN_MAX) { - return (FALSE); + return (false); } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); - return (FALSE); + return (false); } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); - return (FALSE); + return (false); } if (esm_data->pdn[pid].data->bearer[0] != NULL) { @@ -281,7 +281,7 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) } /* The PDN connection has not been activated yet */ - LOG_FUNC_RETURN (TRUE); + LOG_FUNC_RETURN (true); } /**************************************************************************** @@ -301,7 +301,7 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) ** ** ***************************************************************************/ int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, - int *is_emergency, int *is_active) + bool *is_emergency, bool *is_active) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index 6e6ecc0db4..ca8679c5b7 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -69,10 +69,9 @@ void esm_main_cleanup(esm_data_t *esm_data); /* User's getter for PDN connections and EPS bearer contexts */ int esm_main_get_nb_pdns_max(esm_data_t *esm_data); int esm_main_get_nb_pdns(esm_data_t *esm_data); -int esm_main_has_emergency(esm_data_t *esm_data); -int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state); -int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, - int *is_active); +bool esm_main_has_emergency(esm_data_t *esm_data); +bool esm_main_get_pdn_status(nas_user_t *user, int cid, bool *state); +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, bool *is_emergency, bool *is_active); int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr); diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index 941cfa620d..42a925327e 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -79,7 +79,7 @@ typedef enum { * Type of the ESM procedure callback executed when requested by the UE * or initiated by the network */ -typedef int (*esm_proc_procedure_t) (nas_user_t *user, int, int, OctetString *, int); +typedef int (*esm_proc_procedure_t) (nas_user_t *user, bool, int, OctetString *, bool); /* EPS bearer level QoS parameters */ typedef network_qos_t esm_proc_qos_t; @@ -113,8 +113,7 @@ typedef struct { * -------------------------------------------------------------------------- */ int esm_proc_status_ind(int pti, int ebi, int *esm_cause); -int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *msg, - int sent_by_ue); +int esm_proc_status(nas_user_t *user, bool is_standalone, int pti, OctetString *msg, bool sent_by_ue); /* @@ -123,10 +122,10 @@ int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *m * -------------------------------------------------------------------------- */ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int to_define, - esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, + esm_proc_pdn_type_t pdn_type, const OctetString *apn, bool is_emergency, unsigned int *pti); -int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue); +int esm_proc_pdn_connectivity_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue); int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_address, const OctetString *apn, int *esm_cause); int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause); @@ -140,8 +139,8 @@ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending); * -------------------------------------------------------------------------- */ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi); -int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue); +int esm_proc_pdn_disconnect_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue); int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause); int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); @@ -157,10 +156,10 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data); int esm_proc_default_eps_bearer_context_failure(nas_user_t *user); -int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); -int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); /* * -------------------------------------------------------------------------- @@ -171,10 +170,10 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause); -int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); -int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); /* * -------------------------------------------------------------------------- @@ -182,11 +181,11 @@ int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standa * -------------------------------------------------------------------------- */ -int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, bool is_local, int ebi, int *pid, int *bid); int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause); -int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); #endif /* __ESM_PROC_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index f253291fd9..d9f593fb57 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -482,11 +482,11 @@ int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status) ** Inputs: pti: The identity of the procedure transaction ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) +bool esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) { return ( (pti == ESM_PT_UNASSIGNED) || (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) || @@ -504,11 +504,11 @@ int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_reserved(int pti) +bool esm_pt_is_reserved(int pti) { return ( (pti != ESM_PT_UNASSIGNED) && (pti > ESM_PTI_MAX) ); } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index 3179e0f47b..b0c62253ab 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -64,7 +64,7 @@ Description Defines functions used to handle ESM procedure transactions. /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_pt_is_reserved(int pti); +bool esm_pt_is_reserved(int pti); esm_pt_data_t *esm_pt_initialize(void); @@ -79,6 +79,6 @@ int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status); esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti); int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status); -int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); +bool esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); #endif /* __ESM_PT_H__*/ diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 7b9a1be422..a3a1c9c79b 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -205,7 +205,7 @@ static void *_nas_user_mngr(void *args) LOG_FUNC_IN; pthread_setname_np( pthread_self(), "nas_user_mngr"); - int exit_loop = FALSE; + bool exit_loop = false; int *fd = (int *) args; @@ -251,7 +251,7 @@ static void *_nas_network_mngr(void *args) LOG_TRACE (INFO, "UE-MAIN - Network connection manager started (%d)", *fd); /* Network receiving loop */ - while (TRUE) { + while (true) { /* Read the network data message */ bytes = network_api_read_data (*fd); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 9350590788..41230696a4 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -64,8 +64,8 @@ Description NAS procedure call manager #define NAS_PROC_RSRP_UNKNOWN 255 -static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all); -static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all); +static int _nas_proc_activate(nas_user_t *user, int cid, bool apply_to_all); +static int _nas_proc_deactivate(nas_user_t *user, int cid, bool apply_to_all); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -93,7 +93,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, LOG_FUNC_IN; /* Initialize local NAS data */ - user->proc.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = false; user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; @@ -129,7 +129,7 @@ void nas_proc_cleanup(nas_user_t *user) LOG_FUNC_IN; /* Detach the UE from the EPS network */ - int rc = nas_proc_detach(user, TRUE); + int rc = nas_proc_detach(user, true); if (rc != RETURNok) { LOG_TRACE(ERROR, "NAS-PROC - Failed to detach from the network"); @@ -176,7 +176,7 @@ int nas_proc_enable_s1_mode(nas_user_t *user) * Notify the EMM procedure call manager that EPS capability * of the UE is enabled */ - user->proc.EPS_capability_status = TRUE; + user->proc.EPS_capability_status = true; emm_sap.primitive = EMMREG_S1_ENABLED; rc = emm_sap_send(user, &emm_sap); @@ -209,7 +209,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user) * Notify the EMM procedure call manager that EPS capability * of the UE is disabled */ - user->proc.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = false; emm_sap.primitive = EMMREG_S1_DISABLED; rc = emm_sap_send(user, &emm_sap); @@ -231,7 +231,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_eps(nas_user_t *user, int *stat) +int nas_proc_get_eps(nas_user_t *user, bool *stat) { LOG_FUNC_IN; @@ -449,7 +449,7 @@ int nas_proc_deregister(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, bool *selected, int format, network_plmn_t *oper, int *AcT) { LOG_FUNC_IN; @@ -462,12 +462,12 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format if (oper_name != NULL) { /* An operator is currently selected */ - *selected = TRUE; + *selected = true; /* Get the supported Radio Access Technology */ *AcT = emm_main_get_plmn_rat(user->emm_data); } else { /* No any operator is selected */ - *selected = FALSE; + *selected = false; *AcT = NET_ACCESS_UNAVAILABLE; } @@ -558,7 +558,7 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) ** ** ** Description: Initiates a detach procedure ** ** ** - ** Inputs: switch_off: TRUE if the detach is due to UE switch-off ** + ** Inputs: switch_off: true if the detach is due to UE switch-off ** ** Others: None ** ** ** ** Outputs: None ** @@ -566,7 +566,7 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_detach(nas_user_t *user, int switch_off) +int nas_proc_detach(nas_user_t *user, bool switch_off) { LOG_FUNC_IN; @@ -607,7 +607,7 @@ int nas_proc_attach(nas_user_t *user) if ( !emm_main_is_attached(user->emm_data) ) { /* Initiate an Attach procedure */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = FALSE; + emm_sap.u.emm_reg.u.attach.is_emergency = false; rc = emm_sap_send(user, &emm_sap); } @@ -624,16 +624,16 @@ int nas_proc_attach(nas_user_t *user) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached to ** + ** Return: true if the UE is currently attached to ** ** the network ** ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_attach_status(nas_user_t *user) +bool nas_proc_get_attach_status(nas_user_t *user) { LOG_FUNC_IN; - int is_attached = emm_main_is_attached(user->emm_data); + bool is_attached = emm_main_is_attached(user->emm_data); LOG_FUNC_RETURN (is_attached); } @@ -690,10 +690,10 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_ /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get the status of this PDN */ - int state = FALSE; - int is_defined = esm_main_get_pdn_status(user, cid, &state); + bool state = false; + bool is_defined = esm_main_get_pdn_status(user, cid, &state); - if (is_defined != FALSE) { + if (is_defined != false) { /* This PDN has been defined */ *(cids++) = cid; *(states++) = state; @@ -734,7 +734,7 @@ int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const ch /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { - int emergency, active; + bool emergency, active; /* Get PDN connection parameters */ int rc = esm_main_get_pdn(esm_data, cid, types, apns, &emergency, &active); @@ -845,8 +845,8 @@ int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int i esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = FALSE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = false; esm_sap.data.pdn_connect.cid = cid; esm_sap.data.pdn_connect.pdn_type = type; esm_sap.data.pdn_connect.apn = apn; @@ -882,8 +882,8 @@ int nas_proc_reset_pdn(nas_user_t *user, int cid) esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = cid; /* * Notify ESM that the specified PDN context has to be undefined @@ -916,7 +916,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) if (cid > 0) { /* Deactivate only the specified PDN context */ - rc = _nas_proc_deactivate(user, cid, FALSE); + rc = _nas_proc_deactivate(user, cid, false); } else { /* Do not deactivate the PDN connection established during initial * network attachment (identifier 1) */ @@ -924,7 +924,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) /* Deactivate all active PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { - rc = _nas_proc_deactivate(user, cid++, TRUE); + rc = _nas_proc_deactivate(user, cid++, true); } } @@ -970,13 +970,13 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) if (rc != RETURNerror) { if (cid > 0) { /* Activate only the specified PDN context */ - rc = _nas_proc_activate(user, cid, FALSE); + rc = _nas_proc_activate(user, cid, false); } else { cid = 1; /* Activate all defined PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { - rc = _nas_proc_activate(user, cid++, TRUE); + rc = _nas_proc_activate(user, cid++, true); } } } @@ -1177,7 +1177,7 @@ int nas_proc_ul_transfer_cnf(nas_user_t *user) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = TRUE; + emm_sap.u.emm_as.u.data.delivered = true; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1214,7 +1214,7 @@ int nas_proc_ul_transfer_rej(nas_user_t *user) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = FALSE; + emm_sap.u.emm_as.u.data.delivered = false; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1251,7 +1251,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = TRUE; + emm_sap.u.emm_as.u.data.delivered = true; emm_sap.u.emm_as.u.data.NASmsg.length = len; emm_sap.u.emm_as.u.data.NASmsg.value = (uint8_t *)data; rc = emm_sap_send(user, &emm_sap); @@ -1274,7 +1274,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) ** ** ** Inputs: cid: Identifier of the PDN context used to es- ** ** tablished connectivity to specified PDN ** - ** apply_to_all: TRUE if the PDN connectivity procedure is ** + ** apply_to_all: true if the PDN connectivity procedure is ** ** initiated to establish connectivity to all ** ** defined PDNs ** ** Others: None ** @@ -1284,12 +1284,12 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) +static int _nas_proc_activate(nas_user_t *user, int cid, bool apply_to_all) { LOG_FUNC_IN; int rc; - int active = FALSE; + bool active = false; esm_sap_t esm_sap; @@ -1332,8 +1332,8 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) * for the specified PDN */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = cid; rc = esm_sap_send(user, &esm_sap); @@ -1347,7 +1347,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) ** Description: Initiates a PDN disconnect procedure ** ** ** ** Inputs: cid: Identifier of the PDN context ** - ** apply_to_all: TRUE if the PDN disconnect procedure is ** + ** apply_to_all: true if the PDN disconnect procedure is ** ** initiated to request disconnection from ** ** all active PDNs ** ** Others: None ** @@ -1357,15 +1357,15 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) +static int _nas_proc_deactivate(nas_user_t *user, int cid, bool apply_to_all) { LOG_FUNC_IN; int rc; int pdn_type; const char *apn; - int emergency = FALSE; - int active = FALSE; + bool emergency = false; + bool active = false; /* Get PDN context parameters */ rc = esm_main_get_pdn(user->esm_data, cid, &pdn_type, &apn, &emergency, &active); diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 4e653549ae..bd88691de8 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -74,7 +74,7 @@ void nas_proc_cleanup(nas_user_t *user); int nas_proc_enable_s1_mode(nas_user_t *user); int nas_proc_disable_s1_mode(nas_user_t *user); -int nas_proc_get_eps(nas_user_t *user, int *stat); +int nas_proc_get_eps(nas_user_t *user, bool *stat); int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str); int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi); @@ -83,16 +83,16 @@ int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT); int nas_proc_deregister(nas_user_t *user); -int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, bool *selected, int format, network_plmn_t *oper, int *AcT); int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list); int nas_proc_get_reg_status(nas_user_t *user, int *stat); int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT); -int nas_proc_detach(nas_user_t *user, int switch_off); +int nas_proc_detach(nas_user_t *user, bool switch_off); int nas_proc_attach(nas_user_t *user); -int nas_proc_get_attach_status(nas_user_t *user); +bool nas_proc_get_attach_status(nas_user_t *user); int nas_proc_reset_pdn(nas_user_t *user, int cid); int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, diff --git a/openair3/NAS/UE/nas_proc_defs.h b/openair3/NAS/UE/nas_proc_defs.h index 1ce2bfd929..09cf8e834e 100644 --- a/openair3/NAS/UE/nas_proc_defs.h +++ b/openair3/NAS/UE/nas_proc_defs.h @@ -1,12 +1,14 @@ #ifndef _NAS_PROC_DEFS_H #define _NAS_PROC_DEFS_H +#include + /* * Local NAS data */ typedef struct { /* EPS capibility status */ - int EPS_capability_status; + bool EPS_capability_status; /* Reference signal received quality */ int rsrq; /* Reference signal received power */ diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index a94445349c..34bf6cb3ad 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -43,10 +43,10 @@ uint16_t ue_idx_standalone = 0xFFFF; char *make_port_str_from_ueid(const char *base_port_str, int ueid); -static int nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) +static bool nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) { int event; - int exit_loop = FALSE; + bool exit_loop = false; LOG_I(NAS, "[UE] Received %d events\n", nb_events); @@ -310,7 +310,7 @@ void *nas_ue_task(void *args_p) nb_events = itti_get_events(TASK_NAS_UE, &events); if ((nb_events > 0) && (events != NULL)) { - if (nas_ue_process_events(users, events, nb_events) == TRUE) { + if (nas_ue_process_events(users, events, nb_events) == true) { LOG_E(NAS, "[UE] Received exit loop\n"); } } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index d3467eddd5..56e41e4610 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -187,10 +187,10 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, ** from which data have been received ** ** Others: None ** ** ** - ** Outputs: Return: FALSE, TRUE ** + ** Outputs: Return: false, true ** ** ** ***************************************************************************/ -int nas_user_receive_and_process(nas_user_t *user, char *message) +bool nas_user_receive_and_process(nas_user_t *user, char *message) { LOG_FUNC_IN; @@ -212,13 +212,13 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) * exit from the receiving loop */ LOG_TRACE (ERROR, "UE-MAIN - " "Failed to read data from the user application layer"); - LOG_FUNC_RETURN(TRUE); + LOG_FUNC_RETURN(true); } } if (bytes == 0) { /* A signal was caught before any data were available */ - LOG_FUNC_RETURN(FALSE); + LOG_FUNC_RETURN(false); } /* Decode the user data message */ @@ -268,12 +268,12 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) * exit from the receiving loop */ LOG_TRACE (ERROR, "UE-MAIN - " "Failed to send data to the user application layer"); - LOG_FUNC_RETURN(TRUE); + LOG_FUNC_RETURN(true); } } } - LOG_FUNC_RETURN(FALSE); + LOG_FUNC_RETURN(false); } /**************************************************************************** @@ -989,7 +989,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) char oper_buffer[NET_FORMAT_MAX_SIZE], *oper = oper_buffer; memset(oper, 0, NET_FORMAT_MAX_SIZE); - int oper_is_selected; + bool oper_is_selected; at_response->id = data->id; at_response->type = data->type; @@ -1266,7 +1266,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) if (data->command.cgatt.state == AT_CGATT_ATTACHED) { ret_code = nas_proc_attach(user); } else if (data->command.cgatt.state == AT_CGATT_DETACHED) { - ret_code = nas_proc_detach(user, FALSE); + ret_code = nas_proc_detach(user, false); } if (ret_code != RETURNok) { @@ -1284,7 +1284,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) /* * Read command returns the current EPS service state. */ - if (nas_proc_get_attach_status(user) != TRUE) { + if (nas_proc_get_attach_status(user) != true) { cgatt->state = AT_CGATT_DETACHED; } else { cgatt->state = AT_CGATT_ATTACHED; @@ -1821,7 +1821,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) int emergency = AT_CGDCONT_EBS_DEFAULT; int p_cscf = AT_CGDCONT_PCSCF_DEFAULT; int im_cn_signalling = AT_CGDCONT_IM_CM_DEFAULT; - int reset_pdn = TRUE; + bool reset_pdn = true; at_response->id = data->id; at_response->type = data->type; @@ -1870,7 +1870,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) break; } - reset_pdn = FALSE; + reset_pdn = false; } if (data->mask & AT_CGDCONT_APN_MASK) { diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 1ded438ddd..63920540d4 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -63,7 +63,7 @@ Description NAS procedure functions triggered by the user void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version); -int nas_user_receive_and_process(nas_user_t *user, char *message); +bool nas_user_receive_and_process(nas_user_t *user, char *message); int nas_user_process_data(nas_user_t *user, const void *data); diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h index 60f7beacd0..cfb9d63e59 100644 --- a/openair3/NGAP/ngap_common.h +++ b/openair3/NGAP/ngap_common.h @@ -33,23 +33,11 @@ */ -#if HAVE_CONFIG_H_ -# include "config.h" -#endif - #ifndef NGAP_COMMON_H_ #define NGAP_COMMON_H_ #include "common/utils/LOG/log.h" -/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system - Would be cleaner to modify asn_internal.h but it seems to come - from non oai source, with BSD license, so prefer to do that here.. -*/ -#ifdef ASN_DEBUG -# undef ASN_DEBUG -#endif -#define ASN_DEBUG( x... ) LOG_I(ASN, x) #include "NGAP_ProtocolIE-Field.h" #include "NGAP_NGAP-PDU.h" @@ -102,13 +90,6 @@ # error "You are compiling ngap with the wrong version of ASN1C" #endif -#ifndef FALSE -# define FALSE (0) -#endif -#ifndef TRUE -# define TRUE (!FALSE) -#endif - #define NGAP_UE_ID_FMT "0x%06"PRIX32 extern int asn_debug; diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 9d6bd7f07f..59e275ad53 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -494,7 +494,7 @@ static int ngap_gNB_generate_ng_setup_request( ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t)); INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST); - if(instance_p->s_nssai[i]->sD_flag) { + if (instance_p->s_nssai[i][si].sD_flag) { ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t)); ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t)); ssi->s_NSSAI.sD->size = 3; diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index d7db2f70b4..976a4220dd 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -1369,15 +1369,6 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, item->pDUSessionResourceReleaseResponseTransfer.size = 0; item->pDUSessionResourceReleaseResponseTransfer.buf = NULL; NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n"); -#ifdef ITTI_SIM - //For testing only - item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1); - item->pDUSessionResourceReleaseResponseTransfer.size = 1; - uint8_t temp = 0; - memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf, - &temp, - item->pDUSessionResourceReleaseResponseTransfer.size); -#endif } NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 3c07f92a7f..9eee0d8dff 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -23,24 +23,10 @@ * @ingroup _ref_implementation_ * @{ */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif - #ifndef S1AP_COMMON_H_ #define S1AP_COMMON_H_ - #include "common/utils/LOG/log.h" -/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system - Would be cleaner to modify asn_internal.h but it seems to come - from non oai source, with BSD license, so prefer to do that here.. -*/ -#ifdef ASN_DEBUG -# undef ASN_DEBUG -#endif -#define ASN_DEBUG( x... ) LOG_I(ASN, x) #include "S1AP_ProtocolIE-Field.h" #include "S1AP_S1AP-PDU.h" @@ -61,16 +47,8 @@ # error "You are compiling s1ap with the wrong version of ASN1C" #endif -#ifndef FALSE -# define FALSE (0) -#endif -#ifndef TRUE -# define TRUE (!FALSE) -#endif - #define S1AP_UE_ID_FMT "0x%06"PRIX32 -extern int asn_debug; extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c index 695eeb4ef8..de84682ec1 100644 --- a/openair3/S1AP/s1ap_eNB_trace.c +++ b/openair3/S1AP/s1ap_eNB_trace.c @@ -115,7 +115,7 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.TraceStart; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_TraceStartIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, TRUE); + S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); mme_ref_p = s1ap_eNB_get_MME(NULL, assoc_id, 0); DevAssert(mme_ref_p != NULL); if (ie != NULL) { diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 06e606e36b..df6dde0f99 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -859,7 +859,7 @@ sctp_eNB_accept_associations( struct sctp_cnx_list_elm_s *sctp_cnx) { int client_sd; - struct sockaddr saddr; + struct sockaddr_in6 saddr; socklen_t saddr_size; DevAssert(sctp_cnx != NULL); @@ -868,14 +868,14 @@ sctp_eNB_accept_associations( /* There is a new client connecting. Accept it... */ - if ((client_sd = accept(sctp_cnx->sd, &saddr, &saddr_size)) < 0) { + if ((client_sd = accept(sctp_cnx->sd, (struct sockaddr*)&saddr, &saddr_size)) < 0) { SCTP_ERROR("[%d] accept failed: %s:%d\n", sctp_cnx->sd, strerror(errno), errno); } else { struct sctp_cnx_list_elm_s *new_cnx; uint16_t port; /* This is an ipv6 socket */ - port = ((struct sockaddr_in6*)&saddr)->sin6_port; + port = saddr.sin6_port; /* Contrary to BSD, client socket does not inherit O_NONBLOCK option */ if (fcntl(client_sd, F_SETFL, O_NONBLOCK) < 0) { diff --git a/openair3/TEST/test_kdf.c b/openair3/TEST/test_kdf.c index 50a2ad347a..7e1b623e5e 100644 --- a/openair3/TEST/test_kdf.c +++ b/openair3/TEST/test_kdf.c @@ -24,10 +24,6 @@ #include #include -#if HAVE_CONFIG_H -# include "config.h" -#endif - #include "test_util.h" #include "secu_defs.h" diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index 00b650a302..0361c34f33 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -70,8 +70,8 @@ /* Convert an integer on 16 bits to the given bUFFER */ #define INT16_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 8; \ - (buf)[1] = (x); \ + (buf)[0] = ((x) >> 8) & 0xff; \ + (buf)[1] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ @@ -84,9 +84,9 @@ do { \ /* Convert an integer on 24 bits to the given bUFFER */ #define INT24_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 16; \ - (buf)[1] = (x) >> 8; \ - (buf)[2] = (x); \ + (buf)[0] = ((x) >> 16) & 0xff;\ + (buf)[1] = ((x) >> 8) & 0xff; \ + (buf)[2] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ @@ -101,10 +101,10 @@ do { \ /* Convert an integer on 32 bits to the given bUFFER */ #define INT32_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 24; \ - (buf)[1] = (x) >> 16; \ - (buf)[2] = (x) >> 8; \ - (buf)[3] = (x); \ + (buf)[0] = ((x) >> 24) & 0xff;\ + (buf)[1] = ((x) >> 16) & 0xff;\ + (buf)[2] = ((x) >> 8) & 0xff; \ + (buf)[3] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 9537f9e18a..dc93960e5e 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -17,11 +17,10 @@ extern "C" { #include #include #include +#include #include "openair2/SDAP/nr_sdap/nr_sdap.h" //#include -static boolean_t is_gnb = false; - #pragma pack(1) typedef struct Gtpv1uMsgHeader { @@ -36,6 +35,22 @@ typedef struct Gtpv1uMsgHeader { teid_t teid; } __attribute__((packed)) Gtpv1uMsgHeaderT; +//TS 38.425, Figure 5.5.2.2-1 +typedef struct DlDataDeliveryStatus_flags { + uint8_t LPR:1; //Lost packet report + uint8_t FFI:1; //Final Frame Ind + uint8_t deliveredPdcpSn:1; //Highest Delivered NR PDCP SN Ind + uint8_t transmittedPdcpSn:1; //Highest Transmitted NR PDCP SN Ind + uint8_t pduType:4; //PDU type + uint8_t CR:1; //Cause Report + uint8_t deliveredReTxPdcpSn:1; //Delivered retransmitted NR PDCP SN Ind + uint8_t reTxPdcpSn:1; //Retransmitted NR PDCP SN Ind + uint8_t DRI:1; //Data Rate Indication + uint8_t deliveredPdcpSnRange:1; //Delivered NR PDCP SN Range Ind + uint8_t spare:3; + uint32_t drbBufferSize; //Desired buffer size for the data radio bearer +} __attribute__((packed)) DlDataDeliveryStatus_flagsT; + typedef struct Gtpv1uMsgHeaderOptFields { uint8_t seqNum1Oct; uint8_t seqNum2Oct; @@ -43,24 +58,29 @@ typedef struct Gtpv1uMsgHeaderOptFields { uint8_t NextExtHeaderType; } __attribute__((packed)) Gtpv1uMsgHeaderOptFieldsT; -typedef struct PDUSessionContainer { +#define DL_PDU_SESSION_INFORMATION 0 +#define UL_PDU_SESSION_INFORMATION 1 + + typedef struct PDUSessionContainer { uint8_t spare:4; uint8_t PDU_type:4; uint8_t QFI:6; - uint8_t RQI:1; - uint8_t PPP:1; + uint8_t Reflective_QoS_activation:1; + uint8_t Paging_Policy_Indicator:1; } __attribute__((packed)) PDUSessionContainerT; typedef struct Gtpv1uExtHeader { uint8_t ExtHeaderLen; PDUSessionContainerT pdusession_cntr; - //uint8_t NextExtHeaderType; + uint8_t NextExtHeaderType; }__attribute__((packed)) Gtpv1uExtHeaderT; #pragma pack() // TS 29.281, fig 5.2.1-3 #define PDU_SESSION_CONTAINER (0x85) +#define NR_RAN_CONTAINER (0x84) + // TS 29.281, 5.2.1 #define EXT_HDR_LNTH_OCTET_UNITS (4) #define NO_MORE_EXT_HDRS (0) @@ -84,16 +104,19 @@ typedef struct gtpv1u_bearer_s { tcp_udp_port_t outgoing_port; uint16_t seqNum; uint8_t npduNum; + int outgoing_qfi; } gtpv1u_bearer_t; typedef struct { map bearers; + teid_t outgoing_teid; } teidData_t; typedef struct { rnti_t rnti; ebi_t incoming_rb_id; gtpCallback callBack; + teid_t outgoing_teid; gtpCallbackSDAP callBackSDAP; int pdusession_id; } rntiData_t; @@ -137,53 +160,81 @@ instance_t legacyInstanceMapping=0; #define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a) #define GTPV1U_HEADER_SIZE (8) + + #define HDR_MAX 256 // 256 is supposed to be larger than any gtp header +static int gtpv1uCreateAndSendMsg(int h, + uint32_t peerIp, + uint16_t peerPort, + int msgType, + teid_t teid, + uint8_t *Msg, + int msgLen, + bool seqNumFlag, + bool npduNumFlag, + int seqNum, + int npduNum, + int extHdrType, + uint8_t *extensionHeader_buffer, + uint8_t extensionHeader_length) { + LOG_D(GTPU, "Peer IP:%u peer port:%u outgoing teid:%u \n", peerIp, peerPort, teid); - -static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, int msgType, teid_t teid, uint8_t *Msg,int msgLen, - bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { - AssertFatal(extHdrFlag==false,"Not developped"); - int headerAdditional=0; - - if ( seqNumFlag || npduNumFlag || extHdrFlag) - headerAdditional=4; - - int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen; - uint8_t buffer[fullSize]; + uint8_t buffer[msgLen+HDR_MAX]; + uint8_t *curPtr=buffer; Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ; // N should be 0 for us (it was used only in 2G and 3G) msgHdr->PN=npduNumFlag; msgHdr->S=seqNumFlag; - msgHdr->E=extHdrFlag; + msgHdr->E = extHdrType != NO_MORE_EXT_HDRS; msgHdr->spare=0; //PT=0 is for GTP' TS 32.295 (charging) msgHdr->PT=1; msgHdr->version=1; msgHdr->msgType=msgType; - msgHdr->msgLength=htons(msgLen); - - if ( seqNumFlag || extHdrFlag || npduNumFlag) - msgHdr->msgLength+=4; - + msgHdr->msgLength = htons(msgLen + extensionHeader_length); msgHdr->teid=htonl(teid); - if(seqNumFlag || extHdrFlag || npduNumFlag) { - *((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000; - *((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00; - *((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00; + curPtr+=sizeof(Gtpv1uMsgHeaderT); + + if (seqNumFlag || (extHdrType != NO_MORE_EXT_HDRS) || npduNumFlag) { + msgHdr->msgLength += htons(4); + *(uint16_t *)curPtr = seqNumFlag ? seqNum : 0x0000; + curPtr+=sizeof(uint16_t); + *(uint8_t *)curPtr = npduNumFlag ? npduNum : 0x00; + curPtr++; + *(uint8_t *)curPtr = extHdrType; + curPtr++; } - memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen); + // Bug: if there is more than one extension, infinite loop on extensionHeader_buffer + while (extHdrType != NO_MORE_EXT_HDRS) { + if (extensionHeader_length > 0) { + memcpy(curPtr, extensionHeader_buffer, extensionHeader_length); + curPtr += extensionHeader_length; + LOG_D(GTPU, "Extension Header for DDD added. The length is: %d, extension header type is: %x \n", extensionHeader_length, *((uint8_t *)(buffer + 11))); + extHdrType = extensionHeader_buffer[extensionHeader_length - 1]; + LOG_D(GTPU, "Next extension header type is: %x \n", *((uint8_t *)(buffer + 11))); + } else { + LOG_W(GTPU, "Extension header type not supported, returning... \n"); + } + } + + if (Msg!= NULL){ + memcpy(curPtr, Msg, msgLen); + curPtr+=msgLen; + } + + AssertFatal(curPtr-(buffer+msgLen) < HDR_MAX, ""); // Fix me: add IPv6 support, using flag ipVersion static struct sockaddr_in to= {0}; to.sin_family = AF_INET; to.sin_port = htons(peerPort); to.sin_addr.s_addr = peerIp ; - LOG_D(GTPU,"sending packet size: %d to %s\n",fullSize, inet_ntoa(to.sin_addr) ); + LOG_D(GTPU,"sending packet size: %ld to %s\n",curPtr-buffer, inet_ntoa(to.sin_addr) ); int ret; - if ((ret=sendto(h, (void *)buffer, (size_t)fullSize, 0,(struct sockaddr *)&to, sizeof(to) )) != fullSize ) { - LOG_E(GTPU, "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %u, ret: %d, errno: %d\n", - h, IPV4_ADDR_FORMAT(peerIp), peerPort, fullSize, ret, errno); + if ((ret=sendto(h, (void *)buffer, curPtr-buffer, 0,(struct sockaddr *)&to, sizeof(to) )) != curPtr-buffer ) { + LOG_E(GTPU, "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %lu, ret: %d, errno: %d\n", + h, IPV4_ADDR_FORMAT(peerIp), peerPort, curPtr-buffer, ret, errno); return GTPNOK; } @@ -225,12 +276,8 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b // copy to release the mutex gtpv1u_bearer_t tmp=ptr2->second; pthread_mutex_unlock(&globGtp.gtp_lock); - gtpv1uCreateAndSendMsg(compatInst(instance), - tmp.outgoing_ip_addr, - tmp.outgoing_port, - GTP_GPDU, - tmp.teid_outgoing, - buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, buffer, length, seqNumFlag, npduNumFlag, tmp.seqNum, tmp.npduNum, NO_MORE_EXT_HDRS, NULL, 0); } static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) { @@ -268,12 +315,98 @@ static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, // copy to release the mutex gtpv1u_bearer_t tmp=ptr2->second; pthread_mutex_unlock(&globGtp.gtp_lock); - gtpv1uCreateAndSendMsg(compatInst(instance), - tmp.outgoing_ip_addr, - tmp.outgoing_port, - GTP_GPDU, - tmp.teid_outgoing, - buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; + + if (tmp.outgoing_qfi != -1) { + Gtpv1uExtHeaderT ext = { 0 }; + ext.ExtHeaderLen = 1; // in quad bytes EXT_HDR_LNTH_OCTET_UNITS + ext.pdusession_cntr.spare = 0; + ext.pdusession_cntr.PDU_type = UL_PDU_SESSION_INFORMATION; + ext.pdusession_cntr.QFI = tmp.outgoing_qfi; + ext.pdusession_cntr.Reflective_QoS_activation = false; + ext.pdusession_cntr.Paging_Policy_Indicator = false; + ext.NextExtHeaderType = NO_MORE_EXT_HDRS; + + gtpv1uCreateAndSendMsg(compatInst(instance), + tmp.outgoing_ip_addr, + tmp.outgoing_port, + GTP_GPDU, + tmp.teid_outgoing, + buffer, + length, + seqNumFlag, + npduNumFlag, + tmp.seqNum, + tmp.npduNum, + PDU_SESSION_CONTAINER, + (uint8_t *)&ext, + sizeof(ext)); + } else { + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, buffer, length, seqNumFlag, npduNumFlag, tmp.seqNum, tmp.npduNum, NO_MORE_EXT_HDRS, NULL, 0); + } +} + +static void fillDlDeliveryStatusReport(extensionHeader_t *extensionHeader, uint32_t RLC_buffer_availability, uint32_t NR_PDCP_PDU_SN){ + + extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+(NR_PDCP_PDU_SN>0?3:0)+(NR_PDCP_PDU_SN>0?1:0)+1)/4; + DlDataDeliveryStatus_flagsT DlDataDeliveryStatus; + DlDataDeliveryStatus.deliveredPdcpSn = 0; + DlDataDeliveryStatus.transmittedPdcpSn= NR_PDCP_PDU_SN>0?1:0; + DlDataDeliveryStatus.pduType = 1; + DlDataDeliveryStatus.drbBufferSize = htonl(RLC_buffer_availability); + memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT)); + uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1; + + if(NR_PDCP_PDU_SN>0){ + extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff; + extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff; + extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff; + LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]); + extensionHeader->buffer[offset+3] = 0x00; //Padding octet + offset = offset+3; + } + extensionHeader->buffer[offset] = 0x00; //No more extension headers + /*Total size of DDD_status PDU = size of mandatory part + + * 3 octets for highest transmitted/delivered PDCP SN + + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+ + (NR_PDCP_PDU_SN>0?3:0)+ + (NR_PDCP_PDU_SN>0?1:0)+1; +} + +static void gtpv1uSendDlDeliveryStatus(instance_t instance, gtpv1u_DU_buffer_report_req_t *req){ + rnti_t rnti=req->rnti; + int rab_id=req->pdusession_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "[%ld] GTP-U gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", instance, rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + map::iterator ptr2=ptrRnti->second.bearers.find(rab_id); + + if ( ptr2 == ptrRnti->second.bearers.end() ) { + LOG_D(GTPU,"GTP-U instance: %ld sending a packet to a non existant RNTI:RAB: %x/%x\n", instance, rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + extensionHeader_t *extensionHeader; + extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t)); + fillDlDeliveryStatusReport(extensionHeader, req->buffer_availability,0); + + LOG_I(GTPU,"[%ld] GTP-U sending DL Data Delivery status to RNTI:RAB:teid %x/%x/%x, oldseq %d, oldnum %d\n", + instance, rnti, rab_id,ptr2->second.teid_outgoing, ptr2->second.seqNum,ptr2->second.npduNum ); + // copy to release the mutex + gtpv1u_bearer_t tmp=ptr2->second; + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length); } static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) { @@ -455,8 +588,16 @@ void GtpuUpdateTunnelOutgoingTeid(instance_t instance, rnti_t rnti, ebi_t bearer return; } -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int outgoing_qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { pthread_mutex_lock(&globGtp.gtp_lock); instance=compatInst(instance); auto inst=&globGtp.instances[instance]; @@ -478,9 +619,11 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id; + inst->te2ue_mapping[incoming_teid].outgoing_teid= outgoing_teid; + inst->te2ue_mapping[incoming_teid].callBack=callBack; - - inst->te2ue_mapping[incoming_teid].callBackSDAP = sdap_data_req; + + inst->te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP; inst->te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id; @@ -511,6 +654,7 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer tmp->teid_incoming = incoming_teid; tmp->outgoing_port=port; tmp->teid_outgoing= outgoing_teid; + tmp->outgoing_qfi=outgoing_qfi; pthread_mutex_unlock(&globGtp.gtp_lock); char ip4[INET_ADDRSTRLEN]; char ip6[INET6_ADDRSTRLEN]; @@ -539,12 +683,16 @@ int gtpv1u_create_s1u_tunnel(instance_t instance, "From legacy code not clear, seems impossible (bearer=%d)\n", create_tunnel_req->eps_bearer_id[i]); int incoming_rb_id=create_tunnel_req->eps_bearer_id[i]-4; - teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, - incoming_rb_id, - create_tunnel_req->eps_bearer_id[i], - create_tunnel_req->sgw_S1u_teid[i], - create_tunnel_req->sgw_addr[i], dstport, - pdcp_data_req); + teid_t teid = newGtpuCreateTunnel(compatInst(instance), + create_tunnel_req->rnti, + incoming_rb_id, + create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->sgw_S1u_teid[i], + -1, // no pdu session in 4G + create_tunnel_req->sgw_addr[i], + dstport, + pdcp_data_req, + NULL); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; @@ -601,15 +749,18 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance, create_tunnel_req->rnti, create_tunnel_req->num_tunnels, create_tunnel_req->outgoing_teid[0]); - tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport(); - is_gnb = true; + tcp_udp_port_t dstport = globGtp.instances[compatInst(instance)].get_dstport(); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { - teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti, - create_tunnel_req->incoming_rb_id[i], - create_tunnel_req->pdusession_id[i], - create_tunnel_req->outgoing_teid[i], - create_tunnel_req->dst_addr[i], dstport, - pdcp_data_req); + teid_t teid = newGtpuCreateTunnel(instance, + create_tunnel_req->rnti, + create_tunnel_req->incoming_rb_id[i], + create_tunnel_req->pdusession_id[i], + create_tunnel_req->outgoing_teid[i], + create_tunnel_req->outgoing_qfi[i], + create_tunnel_req->dst_addr[i], + dstport, + pdcp_data_req, + sdap_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; @@ -739,9 +890,7 @@ static int Gtpv1uHandleEchoReq(int h, uint16_t seq=ntohs(*(uint16_t *)(msgHdr+1)); LOG_D(GTPU, "[%d] Received a echo request, TEID: %d, seq: %hu\n", h, msgHdr->teid, seq); uint8_t recovery[2]= {14,0}; - return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid), - recovery, sizeof recovery, - 1, 0, 0, seq, 0, 0); + return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid), recovery, sizeof recovery, true, false, seq, 0, NO_MORE_EXT_HDRS, NULL, 0); } static int Gtpv1uHandleError(int h, @@ -850,26 +999,63 @@ static int Gtpv1uHandleGpdu(int h, return GTPNOK; } - int offset=sizeof(Gtpv1uMsgHeaderT); + /* see TS 29.281 5.1 */ + //Minimum length of GTP-U header if non of the optional fields are present + int offset = sizeof(Gtpv1uMsgHeaderT); - uint8_t qfi = 0; - boolean_t rqi = FALSE; + uint8_t qfi = -1; + bool rqi = false; + uint32_t NR_PDCP_PDU_SN = 0; - if( msgHdr->E || msgHdr->S || msgHdr->PN){ - Gtpv1uMsgHeaderOptFieldsT *msgHdrOpt = (Gtpv1uMsgHeaderOptFieldsT *)(msgBuf+offset); - offset+=sizeof(Gtpv1uMsgHeaderOptFieldsT); - if( msgHdr->E && msgHdrOpt->NextExtHeaderType == PDU_SESSION_CONTAINER){ - Gtpv1uExtHeaderT *msgHdrExt = (Gtpv1uExtHeaderT *)(msgBuf+offset); - offset+=msgHdrExt->ExtHeaderLen*EXT_HDR_LNTH_OCTET_UNITS; - qfi = msgHdrExt->pdusession_cntr.QFI; - rqi = msgHdrExt->pdusession_cntr.RQI; + /* if E, S, or PN is set then there are 4 more bytes of header */ + if( msgHdr->E || msgHdr->S ||msgHdr->PN) + offset += 4; - /* - * Check if the next extension header type of GTP extension header is set to 0 - * We can not put it in the struct Gtpv1uExtHeaderT because the length is dynamic. - */ - if(*(msgBuf+offset-1) != NO_MORE_EXT_HDRS) - LOG_W(GTPU, "Warning - Next extension header is not zero, handle it \n"); + if (msgHdr->E) { + int next_extension_header_type = msgBuf[offset - 1]; + int extension_header_length; + + while (next_extension_header_type != NO_MORE_EXT_HDRS) { + extension_header_length = msgBuf[offset]; + switch (next_extension_header_type) { + case PDU_SESSION_CONTAINER: { + PDUSessionContainerT *pdusession_cntr = (PDUSessionContainerT *)(msgBuf + offset + 1); + qfi = pdusession_cntr->QFI; + rqi = pdusession_cntr->Reflective_QoS_activation; + break; + } + case NR_RAN_CONTAINER: { + uint8_t PDU_type = (msgBuf[offset+1]>>4) & 0x0f; + if (PDU_type == 0){ //DL USER Data Format + int additional_offset = 6; //Additional offset capturing the first non-mandatory octet (TS 38.425, Figure 5.5.2.1-1) + if(msgBuf[offset+1]>>2 & 0x1){ //DL Discard Blocks flag is present + LOG_I(GTPU, "DL User Data: DL Discard Blocks handling not enabled\n"); + additional_offset = additional_offset + 9; //For the moment ignore + } + if(msgBuf[offset+1]>>1 & 0x1){ //DL Flush flag is present + LOG_I(GTPU, "DL User Data: DL Flush handling not enabled\n"); + additional_offset = additional_offset + 3; //For the moment ignore + } + if((msgBuf[offset+2]>>3)& 0x1){ //"Report delivered" enabled (TS 38.425, 5.4) + /*Store the NR PDCP PDU SN for which a delivery status report shall be generated once the + *PDU gets forwarded to the lower layers*/ + //NR_PDCP_PDU_SN = msgBuf[offset+6] << 16 | msgBuf[offset+7] << 8 | msgBuf[offset+8]; + NR_PDCP_PDU_SN = msgBuf[offset+additional_offset] << 16 | msgBuf[offset+additional_offset+1] << 8 | msgBuf[offset+additional_offset+2]; + LOG_D(GTPU, " NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); + } + } + else{ + LOG_W(GTPU, "NR-RAN container type: %d not supported \n", PDU_type); + } + break; + } + default: + LOG_W(GTPU, "unhandled extension 0x%2.2x, skipping\n", next_extension_header_type); + break; + } + + offset += extension_header_length * EXT_HDR_LNTH_OCTET_UNITS; + next_extension_header_type = msgBuf[offset - 1]; } } @@ -896,7 +1082,7 @@ static int Gtpv1uHandleGpdu(int h, const uint32_t destinationL2Id=0; pthread_mutex_unlock(&globGtp.gtp_lock); - if(is_gnb && qfi){ + if (qfi != -1 && tunnel->second.callBackSDAP) { if ( !tunnel->second.callBackSDAP(&ctxt, srb_flag, rb_id, @@ -925,6 +1111,40 @@ static int Gtpv1uHandleGpdu(int h, LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h); } + if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){ + LOG_D (GTPU, "Create and send DL DATA Delivery status for the previously received PDU, NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id); + LOG_D(GTPU, "Available buffer size in RLC for Tx: %d \n", rlc_tx_buffer_space); + /*Total size of DDD_status PDU = 1 octet to report extension header length + * size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader_t *extensionHeader; + extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t)) ; + extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1)/4; + DlDataDeliveryStatus_flagsT DlDataDeliveryStatus; + DlDataDeliveryStatus.deliveredPdcpSn = 0; + DlDataDeliveryStatus.transmittedPdcpSn= 1; + DlDataDeliveryStatus.pduType = 1; + DlDataDeliveryStatus.drbBufferSize = htonl(rlc_tx_buffer_space); //htonl(10000000); //hardcoded for now but normally we should extract it from RLC + memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT)); + uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1; + + extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff; + extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff; + extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff; + LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]); + extensionHeader->buffer[offset+3] = 0x00; //Padding octet + extensionHeader->buffer[offset+4] = 0x00; //No more extension headers + /*Total size of DDD_status PDU = size of mandatory part + + * 3 octets for highest transmitted/delivered PDCP SN + + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1; + gtpv1uCreateAndSendMsg( + h, peerIp, peerPort, GTP_GPDU, inst->te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length); + } + LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h, msgBufLen-offset, ntohl(msgHdr->teid)); @@ -1009,6 +1229,12 @@ void *gtpv1uTask(void *args) { } break; + case GTPV1U_DU_BUFFER_REPORT_REQ:{ + gtpv1uSendDlDeliveryStatus(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_DU_BUFFER_REPORT_REQ(message_p)); + } + break; + case TERMINATE_MESSAGE: break; diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 17882ebf1e..7951c4db09 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -8,32 +8,30 @@ extern "C" { #endif -typedef boolean_t (*gtpCallback)( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id); +typedef bool (*gtpCallback)(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id); -typedef boolean_t (*gtpCallbackSDAP)( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id); +typedef bool (*gtpCallbackSDAP)(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id); typedef struct openAddr_s { char originHost[HOST_NAME_MAX]; @@ -43,6 +41,11 @@ typedef struct openAddr_s { instance_t originInstance; } openAddr_t; +typedef struct extensionHeader_s{ + uint8_t buffer[500]; + uint8_t length; +}extensionHeader_t; + // the init function create a gtp instance and return the gtp instance id // the parameter originInstance will be sent back in each message from gtp to the creator void gtpv1uReceiver(int h); @@ -63,8 +66,16 @@ int gtpv1u_create_x2u_tunnel( // New API -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_rb_id, teid_t teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack); +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_rb_id, + teid_t teid, + int outgoing_qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP); void GtpuUpdateTunnelOutgoingTeid(instance_t instance, rnti_t rnti, ebi_t bearer_id, teid_t newOutgoingTeid); int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti); int newGtpuDeleteTunnels(instance_t instance, rnti_t rnti, int nbTunnels, pdusessionid_t *pdusession_id); diff --git a/rxsigF0.m b/rxsigF0.m deleted file mode 100644 index 3309e1aa6f..0000000000 --- a/rxsigF0.m +++ /dev/null @@ -1,57345 +0,0 @@ -rxsF0 = [173 + j*(-306) --141 + j*(-130) --166 + j*(-246) --107 + j*(-42) --105 + j*(0) --179 + j*(-28) --87 + j*(186) --95 + j*(151) --1 + j*(228) -172 + j*(-62) -110 + j*(-5) --178 + j*(-33) --18 + j*(57) -9 + j*(146) --11 + j*(103) --67 + j*(64) -28 + j*(-375) --72 + j*(-75) --14 + j*(-318) -194 + j*(193) --173 + j*(-228) -295 + j*(119) -203 + j*(-179) --238 + j*(-276) --286 + j*(112) --409 + j*(95) --260 + j*(84) -72 + j*(40) -105 + j*(-120) -57 + j*(66) -58 + j*(173) --170 + j*(-189) -192 + j*(-50) --88 + j*(160) --187 + j*(-132) -120 + j*(41) -239 + j*(-115) -80 + j*(263) --45 + j*(-30) -396 + j*(192) -161 + j*(-11) --325 + j*(296) --64 + j*(-192) --181 + j*(-59) --272 + j*(192) -11 + j*(192) --215 + j*(50) -122 + j*(177) --255 + j*(26) -87 + j*(11) --86 + j*(-129) --199 + j*(199) --238 + j*(163) -29 + j*(134) -175 + j*(81) -30 + j*(-214) --344 + j*(131) -124 + j*(-252) -134 + j*(-325) -224 + j*(-78) -223 + j*(-190) --15 + j*(88) --223 + j*(128) --48 + j*(-223) --109 + j*(-209) --17 + j*(-84) -179 + j*(73) --25 + j*(-81) -6 + j*(88) -8 + j*(83) --75 + j*(38) --119 + j*(51) -15 + j*(199) -140 + j*(42) -44 + j*(-132) --247 + j*(118) -242 + j*(-82) -140 + j*(-258) --98 + j*(28) -262 + j*(107) --141 + j*(-21) -137 + j*(382) -64 + j*(-163) --81 + j*(62) -54 + j*(245) --132 + j*(75) -196 + j*(-219) --146 + j*(211) --64 + j*(64) --146 + j*(-37) --37 + j*(-94) --318 + j*(160) --237 + j*(112) --98 + j*(2) --286 + j*(209) --69 + j*(192) --52 + j*(105) --63 + j*(-35) -119 + j*(59) --19 + j*(-25) -110 + j*(54) -45 + j*(-37) -42 + j*(-107) -57 + j*(74) -190 + j*(105) -246 + j*(20) -233 + j*(93) -290 + j*(180) -232 + j*(-113) -281 + j*(243) -280 + j*(-250) -47 + j*(-245) -144 + j*(-150) --272 + j*(25) --94 + j*(163) --135 + j*(-334) -16 + j*(-211) --165 + j*(214) -88 + j*(34) -27 + j*(-36) --161 + j*(-243) -94 + j*(151) -112 + j*(-66) --180 + j*(48) --77 + j*(-64) --293 + j*(300) --42 + j*(-139) --177 + j*(91) --37 + j*(-39) --88 + j*(216) --123 + j*(1) -141 + j*(-250) -100 + j*(-148) --11 + j*(265) -30 + j*(-212) --9 + j*(146) -281 + j*(223) --166 + j*(141) --7 + j*(-51) -69 + j*(-37) --91 + j*(45) -198 + j*(-225) -560 + j*(-64) --245 + j*(-145) -194 + j*(231) --96 + j*(216) -8 + j*(-158) -117 + j*(42) --42 + j*(132) -97 + j*(178) --182 + j*(-65) --59 + j*(118) -129 + j*(-45) -75 + j*(-6) --88 + j*(20) --425 + j*(35) -140 + j*(424) --40 + j*(116) -27 + j*(-297) -123 + j*(230) -86 + j*(-293) -104 + j*(-127) -47 + j*(-89) -60 + j*(97) --23 + j*(197) --7 + j*(-93) -115 + j*(205) -271 + j*(-159) --56 + j*(159) --57 + j*(556) --48 + j*(-196) --71 + j*(-63) --353 + j*(-221) --84 + j*(-173) -30 + j*(45) --302 + j*(371) -354 + j*(-22) --233 + j*(35) --308 + j*(-202) --433 + j*(-44) --158 + j*(73) -185 + j*(-150) -48 + j*(124) --7 + j*(168) -190 + j*(78) -211 + j*(-9) --71 + j*(-193) --119 + j*(97) --234 + j*(-197) -341 + j*(-197) --346 + j*(74) -105 + j*(17) -57 + j*(-105) --161 + j*(-138) --180 + j*(180) --156 + j*(91) --9 + j*(-139) --87 + j*(165) --64 + j*(-238) -15 + j*(-221) --113 + j*(8) --331 + j*(59) -90 + j*(-150) --136 + j*(-325) -73 + j*(178) --18 + j*(170) -67 + j*(-96) -85 + j*(-37) --9 + j*(-114) --22 + j*(136) --175 + j*(165) --87 + j*(-25) --31 + j*(-152) --301 + j*(-18) -42 + j*(-54) --32 + j*(-168) --74 + j*(163) --54 + j*(-52) --76 + j*(-21) -67 + j*(73) -129 + j*(-255) --270 + j*(203) --112 + j*(-71) --106 + j*(13) -175 + j*(-194) -6 + j*(110) -115 + j*(135) --22 + j*(-50) -143 + j*(220) --17 + j*(-82) --65 + j*(204) --46 + j*(-112) -86 + j*(-199) -3 + j*(-52) -88 + j*(116) -184 + j*(227) --65 + j*(189) --54 + j*(-150) -139 + j*(206) -122 + j*(72) --71 + j*(194) --134 + j*(287) -44 + j*(-124) -13 + j*(-250) --100 + j*(95) --110 + j*(16) -233 + j*(-139) -228 + j*(-39) --252 + j*(133) --122 + j*(-129) -21 + j*(-143) --55 + j*(-144) --199 + j*(14) -110 + j*(-195) -85 + j*(-45) --243 + j*(-35) -59 + j*(-86) --361 + j*(179) -69 + j*(34) --22 + j*(42) --267 + j*(-294) -28 + j*(-84) -40 + j*(-247) --112 + j*(128) -54 + j*(182) -71 + j*(-33) --40 + j*(448) --75 + j*(-132) -10 + j*(-37) -272 + j*(-126) --209 + j*(-100) --98 + j*(58) -72 + j*(391) -25 + j*(21) --126 + j*(-110) --238 + j*(138) -227 + j*(-283) -64 + j*(-523) --42 + j*(392) -103 + j*(-288) --131 + j*(-207) -88 + j*(3) --81 + j*(382) --4 + j*(119) -177 + j*(-137) --95 + j*(228) -39 + j*(-127) --265 + j*(202) -145 + j*(66) --358 + j*(127) --320 + j*(-144) --48 + j*(-260) -119 + j*(37) --359 + j*(49) -257 + j*(-112) -112 + j*(84) -30 + j*(171) -136 + j*(-186) --250 + j*(-115) --274 + j*(-281) --37 + j*(1) -69 + j*(130) --125 + j*(-184) --315 + j*(-75) --93 + j*(104) -64 + j*(-6) -198 + j*(141) --88 + j*(18) -248 + j*(-57) --107 + j*(74) --71 + j*(26) --90 + j*(-21) --282 + j*(-201) -57 + j*(47) --15 + j*(33) --144 + j*(153) --202 + j*(-221) --124 + j*(-175) --146 + j*(-276) --74 + j*(39) --91 + j*(512) -125 + j*(213) -139 + j*(168) --233 + j*(-91) -60 + j*(-132) --36 + j*(-132) -21 + j*(105) --129 + j*(231) --283 + j*(191) -320 + j*(134) --171 + j*(70) --133 + j*(66) -189 + j*(47) -188 + j*(-88) --16 + j*(263) --44 + j*(4) -93 + j*(-2) -33 + j*(2) -30 + j*(211) --114 + j*(-76) -54 + j*(12) --128 + j*(-8) --23 + j*(265) --235 + j*(224) --56 + j*(260) -30 + j*(106) --150 + j*(-223) --37 + j*(-291) --175 + j*(177) --165 + j*(259) --206 + j*(63) -131 + j*(-61) --43 + j*(-186) --90 + j*(14) -79 + j*(-190) --127 + j*(115) -48 + j*(28) --5 + j*(17) --28 + j*(47) -163 + j*(135) -44 + j*(-125) --86 + j*(275) -1 + j*(117) -49 + j*(-62) -147 + j*(80) -85 + j*(84) --31 + j*(-101) -243 + j*(150) --181 + j*(-219) --138 + j*(-10) --214 + j*(-151) -27 + j*(-88) -211 + j*(86) --162 + j*(-350) --455 + j*(77) -237 + j*(30) -18 + j*(189) --131 + j*(119) -18 + j*(96) -85 + j*(78) -182 + j*(155) -6 + j*(250) -195 + j*(-153) --74 + j*(-51) -44 + j*(-60) --234 + j*(221) -359 + j*(-139) --228 + j*(291) --28 + j*(173) --147 + j*(-59) --357 + j*(100) --86 + j*(464) --113 + j*(-74) --282 + j*(356) -16 + j*(-52) -204 + j*(-316) -258 + j*(178) --75 + j*(100) --113 + j*(83) -158 + j*(309) -65 + j*(-170) -91 + j*(-125) --151 + j*(318) --52 + j*(-18) --138 + j*(176) --226 + j*(30) --177 + j*(39) --150 + j*(-13) -35 + j*(-183) -204 + j*(-308) -186 + j*(-243) --115 + j*(-71) -66 + j*(55) --88 + j*(-128) --109 + j*(195) --244 + j*(-90) -175 + j*(-177) -231 + j*(-194) --59 + j*(101) -23 + j*(-8) --117 + j*(209) --16 + j*(-97) -4 + j*(190) --28 + j*(-67) --94 + j*(3) --54 + j*(-21) --27 + j*(83) --127 + j*(-21) -187 + j*(-289) -3 + j*(-82) --1 + j*(-223) --168 + j*(232) --148 + j*(163) -274 + j*(-324) --156 + j*(-82) -384 + j*(162) --91 + j*(94) --37 + j*(10) --66 + j*(330) --85 + j*(-8) -62 + j*(216) --98 + j*(95) -126 + j*(189) -196 + j*(-243) -81 + j*(-42) --250 + j*(-2) -118 + j*(146) --1 + j*(-98) -88 + j*(-234) --151 + j*(25) -175 + j*(235) -36 + j*(-182) --108 + j*(69) -105 + j*(-38) --175 + j*(-36) --327 + j*(-45) -80 + j*(268) -13 + j*(-43) --87 + j*(57) --70 + j*(-112) -192 + j*(71) --369 + j*(-114) -224 + j*(341) --144 + j*(-145) -262 + j*(105) --91 + j*(-185) --6 + j*(116) --344 + j*(-245) -90 + j*(-101) -147 + j*(-123) --76 + j*(-71) -6 + j*(197) --44 + j*(-130) -21 + j*(-84) -448 + j*(74) -175 + j*(-3) --175 + j*(-156) --18 + j*(-110) --95 + j*(-250) --107 + j*(172) --110 + j*(157) -132 + j*(6) -47 + j*(146) -212 + j*(-167) -95 + j*(40) --239 + j*(-44) -97 + j*(134) --104 + j*(-193) --363 + j*(-244) -86 + j*(-1) -72 + j*(-13) -62 + j*(157) -214 + j*(-103) --161 + j*(-3) --252 + j*(-139) -147 + j*(39) -30 + j*(-73) --100 + j*(-203) -159 + j*(-250) --323 + j*(-118) --35 + j*(-88) --76 + j*(-105) --24 + j*(28) --194 + j*(-233) --272 + j*(23) --204 + j*(89) --83 + j*(-110) --88 + j*(110) -254 + j*(-103) -32 + j*(136) -92 + j*(-226) --92 + j*(-203) --136 + j*(94) --283 + j*(-192) -161 + j*(272) --102 + j*(30) -71 + j*(-71) -158 + j*(58) --71 + j*(-139) -220 + j*(-131) -225 + j*(-135) --222 + j*(332) --296 + j*(-165) --156 + j*(-104) --216 + j*(164) -305 + j*(-68) --102 + j*(47) --25 + j*(66) -28 + j*(250) -120 + j*(-64) --120 + j*(-134) --42 + j*(114) -18 + j*(32) --83 + j*(157) -115 + j*(-25) --247 + j*(-110) --53 + j*(206) -170 + j*(-30) --86 + j*(100) -384 + j*(119) --332 + j*(-5) --37 + j*(163) -74 + j*(285) -139 + j*(-320) --286 + j*(18) -21 + j*(313) -125 + j*(50) --30 + j*(530) -153 + j*(24) -115 + j*(-141) --392 + j*(-131) -194 + j*(-179) -167 + j*(211) -161 + j*(133) -101 + j*(-263) --185 + j*(-81) --6 + j*(240) -257 + j*(71) --30 + j*(68) --143 + j*(29) -124 + j*(154) -296 + j*(-67) -360 + j*(-25) -187 + j*(-21) --70 + j*(409) --95 + j*(39) -53 + j*(161) --158 + j*(64) --141 + j*(112) -414 + j*(-13) --153 + j*(-59) --189 + j*(-54) --69 + j*(19) -1 + j*(-12) -191 + j*(192) --133 + j*(-95) --245 + j*(232) -86 + j*(-66) --173 + j*(129) -63 + j*(131) --348 + j*(-260) -143 + j*(-136) --97 + j*(-107) -135 + j*(58) -184 + j*(-80) --7 + j*(363) --285 + j*(-198) --103 + j*(290) -134 + j*(87) --22 + j*(-163) -66 + j*(-226) -182 + j*(54) --204 + j*(-52) --194 + j*(161) --63 + j*(-117) -61 + j*(98) -49 + j*(-33) --152 + j*(40) -177 + j*(-91) -22 + j*(-106) -89 + j*(-54) -37 + j*(-148) -286 + j*(-67) --114 + j*(69) -13 + j*(127) --218 + j*(-8) --154 + j*(19) -73 + j*(138) --132 + j*(16) -185 + j*(117) --136 + j*(351) --121 + j*(98) -184 + j*(-65) -187 + j*(51) -119 + j*(68) --85 + j*(-50) -145 + j*(-25) --8 + j*(61) -137 + j*(325) --124 + j*(-22) -326 + j*(-175) --25 + j*(86) -279 + j*(-95) -8 + j*(159) --4 + j*(186) -390 + j*(-138) --162 + j*(-42) --28 + j*(114) -153 + j*(44) -340 + j*(-112) --300 + j*(-58) --86 + j*(-173) -267 + j*(-119) -209 + j*(74) --279 + j*(105) --37 + j*(-37) --59 + j*(80) --148 + j*(-163) -81 + j*(-156) --163 + j*(80) --73 + j*(378) --189 + j*(190) --35 + j*(-102) --49 + j*(-172) --177 + j*(-221) --4 + j*(215) --297 + j*(1) --94 + j*(-299) -129 + j*(-374) --38 + j*(-16) --21 + j*(-97) --215 + j*(-75) -147 + j*(111) --173 + j*(-72) -92 + j*(-138) -110 + j*(132) -28 + j*(16) --143 + j*(-182) --109 + j*(325) --30 + j*(128) --200 + j*(-168) --148 + j*(-261) -132 + j*(-63) --30 + j*(-14) --238 + j*(-55) --67 + j*(26) --214 + j*(1) --180 + j*(-286) --147 + j*(-66) -205 + j*(41) -152 + j*(-89) -35 + j*(148) --112 + j*(38) -156 + j*(-81) --177 + j*(104) --194 + j*(307) --46 + j*(-199) --290 + j*(35) --170 + j*(28) --23 + j*(214) --78 + j*(-90) --52 + j*(249) --140 + j*(-72) -175 + j*(-34) -103 + j*(115) -266 + j*(-186) -70 + j*(-192) --204 + j*(94) -18 + j*(287) --173 + j*(289) -136 + j*(216) --98 + j*(164) --37 + j*(185) --147 + j*(59) --105 + j*(-132) -51 + j*(139) -68 + j*(165) --330 + j*(-124) --30 + j*(-76) -5 + j*(-193) -209 + j*(-233) -63 + j*(117) --260 + j*(-180) --34 + j*(182) -40 + j*(-52) -97 + j*(-188) --62 + j*(-71) --13 + j*(-250) --15 + j*(234) -243 + j*(-193) -26 + j*(-392) --129 + j*(69) --143 + j*(-115) --108 + j*(56) --52 + j*(282) --7 + j*(-90) -37 + j*(-105) --615 + j*(-199) --74 + j*(85) --322 + j*(-64) -69 + j*(-165) --70 + j*(101) -29 + j*(92) --150 + j*(-327) -54 + j*(89) --398 + j*(186) --102 + j*(-121) --269 + j*(-71) -52 + j*(-62) -170 + j*(-125) -6 + j*(-69) --76 + j*(-327) -35 + j*(139) --3 + j*(-87) --322 + j*(167) -4 + j*(-26) -184 + j*(160) --178 + j*(-75) -109 + j*(62) -50 + j*(54) --64 + j*(-115) --371 + j*(-247) --124 + j*(-45) --211 + j*(-123) -153 + j*(86) --222 + j*(-161) --163 + j*(-173) --17 + j*(263) -171 + j*(27) -287 + j*(105) -31 + j*(-233) --8 + j*(-81) -37 + j*(120) --8 + j*(21) -3 + j*(-138) -95 + j*(202) -511 + j*(81) --117 + j*(-196) -35 + j*(28) --136 + j*(-301) -182 + j*(-140) --60 + j*(-66) --206 + j*(-111) -231 + j*(27) -48 + j*(49) -206 + j*(315) -86 + j*(93) -131 + j*(-232) --161 + j*(6) -22 + j*(306) --307 + j*(-81) --170 + j*(87) -173 + j*(1) --286 + j*(-155) --278 + j*(-192) -10 + j*(-42) --153 + j*(202) -377 + j*(35) -8 + j*(-47) --54 + j*(-46) -138 + j*(-201) -26 + j*(-49) -235 + j*(-73) --143 + j*(-291) --103 + j*(-30) -18 + j*(-281) -311 + j*(122) -9 + j*(-27) --240 + j*(50) --110 + j*(209) -187 + j*(-209) -68 + j*(247) -498 + j*(-59) -161 + j*(-189) --132 + j*(72) --127 + j*(18) --193 + j*(-185) --127 + j*(-276) --104 + j*(235) --26 + j*(165) -148 + j*(-181) -87 + j*(-107) --177 + j*(136) -173 + j*(2) --298 + j*(-63) -218 + j*(29) --330 + j*(-167) -110 + j*(127) --18 + j*(-42) --85 + j*(153) --92 + j*(-119) -23 + j*(115) -149 + j*(-76) --132 + j*(85) --163 + j*(-52) --139 + j*(303) -151 + j*(113) -264 + j*(74) -48 + j*(115) --38 + j*(-9) --232 + j*(262) -412 + j*(123) -28 + j*(108) --53 + j*(-95) --79 + j*(184) --252 + j*(192) -170 + j*(39) -220 + j*(249) --5 + j*(-8) -125 + j*(27) -147 + j*(-80) -25 + j*(-272) -52 + j*(47) -248 + j*(-56) --84 + j*(-51) --93 + j*(-395) --179 + j*(221) --110 + j*(108) -13 + j*(26) -332 + j*(336) -31 + j*(-141) --2 + j*(76) -334 + j*(-79) -28 + j*(86) -307 + j*(-129) --251 + j*(197) --21 + j*(-36) --117 + j*(71) --279 + j*(42) -220 + j*(216) -135 + j*(-161) -345 + j*(-245) -40 + j*(-155) --61 + j*(159) -105 + j*(52) -278 + j*(-63) --40 + j*(35) --47 + j*(326) --171 + j*(-151) -83 + j*(177) --250 + j*(-70) -20 + j*(-68) -87 + j*(-123) --325 + j*(-98) --3 + j*(81) --21 + j*(165) -97 + j*(295) -554 + j*(168) --192 + j*(-154) -14 + j*(-11) --201 + j*(67) --163 + j*(153) --23 + j*(-153) --44 + j*(-7) --18 + j*(63) --110 + j*(-35) -471 + j*(-202) -267 + j*(-194) --140 + j*(-358) --204 + j*(-94) --25 + j*(-147) -59 + j*(199) -58 + j*(-13) --36 + j*(-114) -115 + j*(-163) -190 + j*(226) --142 + j*(-144) -51 + j*(-93) -68 + j*(-77) -1 + j*(-323) -95 + j*(-72) --112 + j*(3) -202 + j*(284) --261 + j*(18) --358 + j*(122) --129 + j*(-37) -80 + j*(-91) -59 + j*(132) -274 + j*(-385) -54 + j*(-131) --49 + j*(-127) --94 + j*(-332) -276 + j*(-44) -332 + j*(139) -13 + j*(-103) --63 + j*(137) -115 + j*(-137) --117 + j*(233) -10 + j*(-170) --358 + j*(-182) --37 + j*(15) -68 + j*(9) -342 + j*(-268) --127 + j*(-199) -141 + j*(-452) --265 + j*(1) --180 + j*(236) --18 + j*(4) -35 + j*(228) --30 + j*(8) -182 + j*(-211) --233 + j*(0) --79 + j*(-53) --159 + j*(100) --29 + j*(-131) --22 + j*(27) --136 + j*(165) -44 + j*(146) --162 + j*(21) -60 + j*(-158) --127 + j*(-2) --11 + j*(191) --139 + j*(9) -315 + j*(115) -175 + j*(-193) --45 + j*(250) -36 + j*(2) -141 + j*(-198) --307 + j*(2) -144 + j*(-59) -122 + j*(-27) --211 + j*(-483) -185 + j*(58) -39 + j*(127) --238 + j*(-109) -106 + j*(345) -76 + j*(33) -239 + j*(207) --109 + j*(-249) --146 + j*(45) --38 + j*(-150) -78 + j*(-186) -8 + j*(71) --207 + j*(-255) -85 + j*(16) --23 + j*(-153) -82 + j*(-11) --10 + j*(116) -162 + j*(-201) -66 + j*(-116) -277 + j*(163) -102 + j*(-358) -54 + j*(10) -37 + j*(-112) -127 + j*(-64) --74 + j*(-93) --54 + j*(214) -149 + j*(-37) --269 + j*(-66) --13 + j*(-220) --120 + j*(76) -97 + j*(75) -238 + j*(-78) -263 + j*(-293) --57 + j*(-131) -127 + j*(-202) -235 + j*(-105) -226 + j*(-18) --107 + j*(-286) -194 + j*(-118) -104 + j*(-121) -21 + j*(117) -380 + j*(92) -22 + j*(-190) -79 + j*(37) -175 + j*(180) -42 + j*(-70) -40 + j*(-174) --36 + j*(-141) --165 + j*(92) -9 + j*(-335) -328 + j*(-194) --198 + j*(-147) -342 + j*(-129) -71 + j*(-201) -176 + j*(-66) -16 + j*(-255) -179 + j*(-119) -89 + j*(133) -144 + j*(-78) -106 + j*(235) -175 + j*(-324) --68 + j*(315) --265 + j*(-374) --28 + j*(14) --213 + j*(106) -106 + j*(-163) -49 + j*(-71) --151 + j*(6) --421 + j*(119) --244 + j*(23) -81 + j*(-57) --259 + j*(-230) -177 + j*(101) --48 + j*(-308) -147 + j*(57) -152 + j*(47) --194 + j*(-25) --116 + j*(356) --68 + j*(149) -7 + j*(-132) --126 + j*(-159) --177 + j*(272) -226 + j*(-257) --158 + j*(51) --73 + j*(214) -47 + j*(-237) -161 + j*(250) -83 + j*(105) -103 + j*(35) -99 + j*(81) --6 + j*(0) --122 + j*(39) --116 + j*(-209) --172 + j*(-250) -179 + j*(-8) --174 + j*(134) --71 + j*(-194) -105 + j*(257) --124 + j*(100) -33 + j*(-117) --73 + j*(53) -144 + j*(-12) --185 + j*(-141) -136 + j*(110) -45 + j*(117) --7 + j*(-195) --86 + j*(172) --23 + j*(-103) --263 + j*(-26) --37 + j*(124) -166 + j*(392) --373 + j*(111) --34 + j*(-202) -63 + j*(299) -474 + j*(273) --264 + j*(-284) --119 + j*(33) -227 + j*(-117) --98 + j*(135) --47 + j*(-141) --158 + j*(-36) -160 + j*(38) --29 + j*(66) -144 + j*(-272) --171 + j*(-107) -357 + j*(-86) --231 + j*(-86) --75 + j*(-76) -216 + j*(156) --13 + j*(-187) --88 + j*(37) -119 + j*(270) -31 + j*(-77) --140 + j*(37) -21 + j*(-17) -211 + j*(-33) --287 + j*(101) --112 + j*(142) --3 + j*(-140) --91 + j*(-151) -150 + j*(-243) --64 + j*(96) --262 + j*(163) -196 + j*(-39) --126 + j*(-71) --161 + j*(102) --125 + j*(35) -292 + j*(98) --6 + j*(192) -107 + j*(-71) -83 + j*(-193) -272 + j*(-25) -235 + j*(67) --87 + j*(-159) --54 + j*(-118) --279 + j*(-4) -29 + j*(-20) -132 + j*(314) --73 + j*(-148) --470 + j*(86) -262 + j*(-260) --76 + j*(-42) -256 + j*(64) --18 + j*(-144) -40 + j*(-151) -75 + j*(-166) --196 + j*(21) --45 + j*(184) -121 + j*(18) --89 + j*(-148) --170 + j*(-18) -338 + j*(-150) --276 + j*(221) --177 + j*(236) -139 + j*(-134) -139 + j*(213) -33 + j*(233) --53 + j*(16) --219 + j*(-206) -301 + j*(-21) -83 + j*(-59) -47 + j*(-66) -325 + j*(-275) -53 + j*(10) --25 + j*(106) -85 + j*(-86) --150 + j*(-16) --172 + j*(-122) -317 + j*(-115) -66 + j*(-1) --176 + j*(4) --47 + j*(-43) --122 + j*(-28) -79 + j*(519) --87 + j*(190) -81 + j*(-124) -149 + j*(-67) --68 + j*(-148) --154 + j*(-199) --127 + j*(94) --21 + j*(-108) --185 + j*(155) --327 + j*(223) -127 + j*(27) -140 + j*(118) -260 + j*(-68) --228 + j*(200) --431 + j*(-226) -97 + j*(153) -68 + j*(25) --226 + j*(245) --83 + j*(133) -23 + j*(45) -70 + j*(52) --4 + j*(-66) --137 + j*(71) --110 + j*(78) -95 + j*(-11) -93 + j*(-266) --163 + j*(103) --246 + j*(-91) --9 + j*(-296) -177 + j*(-14) --151 + j*(-157) -60 + j*(73) -54 + j*(308) -165 + j*(-85) -106 + j*(-66) --205 + j*(-183) -45 + j*(107) -71 + j*(-59) -249 + j*(27) -10 + j*(168) --153 + j*(-134) --40 + j*(208) --214 + j*(156) -77 + j*(220) -115 + j*(103) -52 + j*(-8) --93 + j*(133) --163 + j*(78) -283 + j*(22) --500 + j*(-91) --42 + j*(-286) -25 + j*(143) --62 + j*(350) -303 + j*(157) --164 + j*(-109) -36 + j*(-296) -166 + j*(19) -298 + j*(161) -99 + j*(-253) -37 + j*(-6) --117 + j*(245) -191 + j*(-123) -153 + j*(-14) -107 + j*(77) --71 + j*(-195) -266 + j*(-438) -163 + j*(3) --202 + j*(-173) --95 + j*(62) -11 + j*(337) -33 + j*(-120) -206 + j*(-425) --189 + j*(-49) -183 + j*(118) --66 + j*(144) --214 + j*(-160) -88 + j*(-28) --49 + j*(102) --262 + j*(-225) --136 + j*(-174) --87 + j*(265) --43 + j*(-2) -68 + j*(36) -47 + j*(-197) --139 + j*(194) -14 + j*(332) -89 + j*(-95) --348 + j*(-112) -122 + j*(-240) -221 + j*(132) -170 + j*(-24) -310 + j*(-73) --103 + j*(-392) -61 + j*(-144) -112 + j*(-128) -73 + j*(52) -48 + j*(435) -224 + j*(169) -116 + j*(-322) -91 + j*(-1) --40 + j*(243) -72 + j*(-96) -159 + j*(-83) -69 + j*(30) --173 + j*(316) -322 + j*(-42) -99 + j*(208) -76 + j*(-222) --35 + j*(-66) -4 + j*(-345) --223 + j*(-115) --37 + j*(212) --119 + j*(6) --23 + j*(-83) --25 + j*(-12) --78 + j*(-47) -166 + j*(69) -116 + j*(72) --60 + j*(105) -165 + j*(53) -83 + j*(-57) --48 + j*(337) -35 + j*(-71) --260 + j*(124) --185 + j*(49) --117 + j*(-358) -138 + j*(-20) --103 + j*(-228) --87 + j*(105) --141 + j*(-50) -160 + j*(124) --448 + j*(42) --87 + j*(36) --227 + j*(-343) --188 + j*(-226) --101 + j*(-183) --8 + j*(-93) --264 + j*(-92) -233 + j*(57) -5 + j*(6) --47 + j*(122) -46 + j*(11) --13 + j*(-95) --35 + j*(60) -203 + j*(-5) --267 + j*(25) -112 + j*(-79) -329 + j*(-30) -111 + j*(-98) --238 + j*(286) --76 + j*(-166) -103 + j*(-232) --41 + j*(-90) -28 + j*(182) -190 + j*(-57) -203 + j*(-90) --51 + j*(-117) -74 + j*(120) --161 + j*(-360) -72 + j*(-57) -296 + j*(-36) -146 + j*(-111) -149 + j*(-75) --59 + j*(-81) -104 + j*(-30) -198 + j*(124) --120 + j*(-214) --98 + j*(63) --127 + j*(-165) -284 + j*(-8) --92 + j*(-310) --368 + j*(105) --314 + j*(-363) -184 + j*(265) --100 + j*(-36) --134 + j*(-56) --158 + j*(121) -72 + j*(-204) -130 + j*(44) --209 + j*(-211) -62 + j*(-212) -177 + j*(100) -78 + j*(-333) --42 + j*(-40) --37 + j*(125) -57 + j*(21) -182 + j*(-21) -3 + j*(-171) -243 + j*(-354) -344 + j*(57) --157 + j*(-167) -121 + j*(59) -151 + j*(145) --162 + j*(-107) -181 + j*(-11) --32 + j*(383) -86 + j*(7) --135 + j*(-260) --79 + j*(-11) --136 + j*(-334) -66 + j*(219) -300 + j*(1) --116 + j*(-202) -186 + j*(-223) -228 + j*(400) --150 + j*(-101) -161 + j*(-204) --10 + j*(53) --236 + j*(172) -143 + j*(-182) -10 + j*(272) -55 + j*(184) -32 + j*(-390) --69 + j*(317) --37 + j*(11) --74 + j*(30) -140 + j*(-83) -53 + j*(-136) -200 + j*(-285) --189 + j*(-378) --101 + j*(-253) --25 + j*(78) -17 + j*(-104) --180 + j*(196) --148 + j*(-309) --317 + j*(119) -141 + j*(79) --41 + j*(-72) --162 + j*(-63) --65 + j*(-35) --110 + j*(49) -110 + j*(-48) -19 + j*(92) --148 + j*(14) --102 + j*(280) -139 + j*(43) --36 + j*(-207) -40 + j*(-76) -172 + j*(-279) --35 + j*(224) -414 + j*(-378) -157 + j*(-112) -529 + j*(-307) --1 + j*(-74) --11 + j*(330) -236 + j*(-36) --158 + j*(-353) --215 + j*(-29) -185 + j*(174) --8 + j*(-27) -306 + j*(170) --214 + j*(-102) --73 + j*(37) -199 + j*(-156) -230 + j*(-113) --2 + j*(-106) --80 + j*(204) -40 + j*(-276) -196 + j*(-459) --330 + j*(-98) --267 + j*(83) --15 + j*(-58) --163 + j*(403) --126 + j*(-262) --215 + j*(178) -89 + j*(121) --132 + j*(130) -154 + j*(210) --159 + j*(337) --264 + j*(161) -25 + j*(201) --21 + j*(102) --132 + j*(101) -6 + j*(98) --19 + j*(-328) -62 + j*(-122) --151 + j*(-103) --72 + j*(316) -150 + j*(-520) -438 + j*(378) -144 + j*(462) -161 + j*(15) -42 + j*(-182) --123 + j*(479) --248 + j*(145) --416 + j*(305) -34 + j*(-459) -334 + j*(133) -391 + j*(-385) --167 + j*(324) --98 + j*(104) -444 + j*(-168) -151 + j*(-241) --143 + j*(56) --148 + j*(281) --276 + j*(269) -260 + j*(-255) -173 + j*(-64) -534 + j*(206) --692 + j*(597) -173 + j*(-259) -235 + j*(346) --59 + j*(-310) -124 + j*(334) --416 + j*(-148) -438 + j*(66) --269 + j*(421) --455 + j*(235) -355 + j*(-293) --326 + j*(-148) --332 + j*(-433) --89 + j*(75) -468 + j*(-103) -376 + j*(-51) --180 + j*(12) -91 + j*(-346) --95 + j*(447) --214 + j*(281) -107 + j*(256) -179 + j*(-77) --397 + j*(-168) --208 + j*(528) --342 + j*(282) -212 + j*(-330) --327 + j*(119) -339 + j*(-146) -112 + j*(346) -361 + j*(142) --556 + j*(260) --226 + j*(-152) --368 + j*(-221) --532 + j*(-147) --494 + j*(-18) -614 + j*(-132) -274 + j*(-102) --269 + j*(-486) --263 + j*(134) --486 + j*(426) --143 + j*(-286) --215 + j*(-343) --383 + j*(-17) --139 + j*(245) -346 + j*(157) -2 + j*(60) -264 + j*(64) -304 + j*(-49) -298 + j*(-491) --375 + j*(-129) -170 + j*(109) --226 + j*(-220) -450 + j*(117) --173 + j*(221) --119 + j*(484) --325 + j*(-109) --301 + j*(-263) --227 + j*(-337) --144 + j*(-313) --93 + j*(-265) --14 + j*(-269) --456 + j*(25) --330 + j*(127) --286 + j*(351) -482 + j*(-336) --387 + j*(436) --182 + j*(260) --327 + j*(-333) --502 + j*(-140) --131 + j*(-227) --261 + j*(-309) -183 + j*(195) --160 + j*(-465) --325 + j*(-431) -212 + j*(-549) -19 + j*(-120) -73 + j*(-1) --316 + j*(347) -192 + j*(265) --192 + j*(-124) -260 + j*(417) -431 + j*(-404) -192 + j*(-508) --54 + j*(-424) -370 + j*(18) --393 + j*(-101) -434 + j*(-268) -50 + j*(-37) -504 + j*(-91) -462 + j*(337) --223 + j*(-328) -298 + j*(-308) -140 + j*(-303) --208 + j*(-406) -378 + j*(-223) --325 + j*(105) --467 + j*(-122) -297 + j*(279) --589 + j*(-381) -252 + j*(185) -161 + j*(-177) -348 + j*(605) --329 + j*(116) -122 + j*(-226) --303 + j*(-57) -357 + j*(-264) --152 + j*(-261) --234 + j*(-112) --66 + j*(37) -239 + j*(446) --20 + j*(170) --202 + j*(72) --132 + j*(-164) --121 + j*(-69) --368 + j*(-541) --16 + j*(356) --226 + j*(-168) --274 + j*(-315) -606 + j*(-180) --187 + j*(-28) --444 + j*(333) --466 + j*(-235) --121 + j*(-71) --236 + j*(-49) -506 + j*(-332) -218 + j*(248) --22 + j*(-289) -308 + j*(-8) --85 + j*(414) --154 + j*(360) -46 + j*(-332) -199 + j*(10) --243 + j*(485) --368 + j*(-624) --367 + j*(170) --339 + j*(274) -895 + j*(286) -148 + j*(-251) -167 + j*(156) -195 + j*(205) -27 + j*(-98) -86 + j*(-226) --197 + j*(-206) -417 + j*(-226) -308 + j*(503) -401 + j*(-250) --139 + j*(158) -108 + j*(190) -462 + j*(257) -14 + j*(-387) -360 + j*(155) --435 + j*(-99) -361 + j*(416) -258 + j*(-62) -25 + j*(-333) -66 + j*(352) -546 + j*(-286) --180 + j*(-458) -280 + j*(-151) -72 + j*(-216) --368 + j*(403) -464 + j*(527) --344 + j*(-60) --129 + j*(516) --279 + j*(348) --249 + j*(257) -95 + j*(226) -180 + j*(170) --97 + j*(-238) --234 + j*(-164) -148 + j*(-344) --190 + j*(-359) -152 + j*(537) -187 + j*(-93) --264 + j*(311) -100 + j*(115) -329 + j*(-129) --264 + j*(495) -281 + j*(296) --216 + j*(-100) -255 + j*(635) --410 + j*(324) -368 + j*(349) --515 + j*(-427) --296 + j*(-91) --89 + j*(-357) -23 + j*(-220) --39 + j*(-482) -366 + j*(613) -359 + j*(44) -270 + j*(-241) -146 + j*(-653) --220 + j*(441) -269 + j*(125) --350 + j*(321) -284 + j*(12) --209 + j*(-60) -305 + j*(144) --368 + j*(272) -468 + j*(-231) -176 + j*(12) --149 + j*(-216) -424 + j*(-84) --462 + j*(-520) -349 + j*(-377) --361 + j*(166) -165 + j*(238) --78 + j*(201) --188 + j*(330) --70 + j*(-25) --220 + j*(330) --206 + j*(308) -378 + j*(-181) --203 + j*(-356) -501 + j*(-574) -63 + j*(134) --493 + j*(-103) --26 + j*(-341) --390 + j*(158) -69 + j*(249) -279 + j*(358) -441 + j*(-253) --142 + j*(142) --346 + j*(-387) -332 + j*(-606) -187 + j*(240) -431 + j*(-35) -308 + j*(-181) -240 + j*(-338) -240 + j*(-168) --429 + j*(-134) -161 + j*(-89) --460 + j*(-346) --382 + j*(247) --521 + j*(-66) -99 + j*(318) --193 + j*(-20) -148 + j*(551) -366 + j*(200) -560 + j*(-170) -281 + j*(280) --462 + j*(-173) --424 + j*(66) -190 + j*(354) --135 + j*(-346) --283 + j*(-282) -306 + j*(-280) -308 + j*(341) -57 + j*(-380) --439 + j*(-147) -46 + j*(-188) --189 + j*(136) --167 + j*(281) --73 + j*(-352) -286 + j*(165) --353 + j*(152) -255 + j*(-443) -458 + j*(300) -126 + j*(-267) --147 + j*(430) -756 + j*(232) --462 + j*(-200) --246 + j*(368) -392 + j*(501) -593 + j*(-118) --341 + j*(274) -240 + j*(221) --474 + j*(-129) -277 + j*(418) --134 + j*(231) --302 + j*(115) -101 + j*(337) --122 + j*(-20) -503 + j*(-217) -473 + j*(-235) --338 + j*(-158) --43 + j*(472) --428 + j*(-216) --344 + j*(75) --728 + j*(233) --86 + j*(6) -337 + j*(-549) --318 + j*(4) --322 + j*(177) -141 + j*(-152) -445 + j*(85) -260 + j*(178) -54 + j*(128) --45 + j*(103) --320 + j*(307) --640 + j*(-346) --98 + j*(445) --356 + j*(-291) -173 + j*(229) --5 + j*(130) -142 + j*(248) --248 + j*(412) --18 + j*(494) -238 + j*(195) --159 + j*(-196) -338 + j*(211) -767 + j*(-549) -516 + j*(185) -252 + j*(87) --416 + j*(387) -371 + j*(-352) --396 + j*(34) -455 + j*(34) -298 + j*(-147) --377 + j*(119) -214 + j*(-19) --242 + j*(-141) -115 + j*(305) -542 + j*(292) -58 + j*(-453) -199 + j*(-347) --431 + j*(-128) -260 + j*(-252) --175 + j*(491) -535 + j*(-119) -330 + j*(69) --240 + j*(-301) -499 + j*(525) --400 + j*(-455) -549 + j*(636) -247 + j*(-328) --293 + j*(-170) --178 + j*(270) --119 + j*(250) -183 + j*(57) -252 + j*(97) --539 + j*(-34) --353 + j*(-15) --105 + j*(-148) --272 + j*(-336) --338 + j*(-402) --396 + j*(57) -292 + j*(41) --204 + j*(-299) -281 + j*(333) -77 + j*(323) --190 + j*(-385) -426 + j*(-128) -263 + j*(282) -16 + j*(18) -327 + j*(-40) --411 + j*(-99) -387 + j*(91) --238 + j*(166) --72 + j*(11) --508 + j*(233) -244 + j*(-490) --442 + j*(216) -178 + j*(-419) -313 + j*(187) -266 + j*(-521) -390 + j*(-337) -448 + j*(-103) -425 + j*(-349) --151 + j*(310) -283 + j*(-153) -320 + j*(-281) -56 + j*(99) --202 + j*(-406) --141 + j*(-409) -121 + j*(317) -380 + j*(371) --177 + j*(-47) -361 + j*(-379) --448 + j*(-28) -296 + j*(-269) -508 + j*(-238) -659 + j*(-47) --298 + j*(-180) -104 + j*(174) -49 + j*(-67) -233 + j*(-449) -339 + j*(156) -258 + j*(-158) --181 + j*(426) -278 + j*(-175) --68 + j*(-334) -327 + j*(-599) -118 + j*(-216) -45 + j*(-304) --158 + j*(216) --257 + j*(204) -396 + j*(-415) -338 + j*(229) --194 + j*(256) --583 + j*(306) -103 + j*(-457) -185 + j*(-439) -478 + j*(66) --255 + j*(464) --145 + j*(346) --660 + j*(-47) --511 + j*(-410) --288 + j*(453) --258 + j*(250) --115 + j*(-121) -134 + j*(344) -349 + j*(-287) --503 + j*(205) --383 + j*(-410) --470 + j*(240) -325 + j*(-687) -221 + j*(-151) -426 + j*(418) -134 + j*(206) -88 + j*(-121) --111 + j*(362) --305 + j*(-182) -93 + j*(-185) --174 + j*(406) --417 + j*(240) -104 + j*(-155) -146 + j*(375) -618 + j*(146) -134 + j*(196) --393 + j*(343) --454 + j*(-76) -260 + j*(-24) -132 + j*(-68) -242 + j*(426) -106 + j*(-454) --266 + j*(-200) -337 + j*(576) -180 + j*(95) --257 + j*(116) -459 + j*(417) --129 + j*(-160) -142 + j*(-197) -219 + j*(504) -154 + j*(170) -132 + j*(185) -316 + j*(264) --440 + j*(200) -97 + j*(-3) --9 + j*(-173) -249 + j*(-28) -612 + j*(-663) --484 + j*(-26) -419 + j*(425) --228 + j*(330) -4 + j*(-297) -445 + j*(201) -519 + j*(37) -333 + j*(158) -362 + j*(45) -333 + j*(-542) -187 + j*(-188) --148 + j*(-273) --329 + j*(241) --148 + j*(-251) -423 + j*(-16) -90 + j*(-232) --293 + j*(551) --190 + j*(165) --256 + j*(-518) -143 + j*(-260) -463 + j*(-392) --295 + j*(-20) -14 + j*(-130) -2 + j*(293) --354 + j*(-299) -409 + j*(298) -185 + j*(238) -383 + j*(220) -316 + j*(-39) -177 + j*(-8) --269 + j*(-223) --332 + j*(132) --312 + j*(137) --254 + j*(-224) --279 + j*(-206) -103 + j*(276) --81 + j*(235) -106 + j*(-356) --250 + j*(170) -146 + j*(-256) -375 + j*(206) -35 + j*(285) -179 + j*(-480) --4 + j*(262) -286 + j*(339) -349 + j*(3) -262 + j*(-317) --188 + j*(314) -258 + j*(280) --60 + j*(-63) --358 + j*(-431) -355 + j*(-313) -602 + j*(-572) --97 + j*(29) --361 + j*(112) -426 + j*(-446) --334 + j*(-248) --468 + j*(-301) --134 + j*(-296) -344 + j*(-398) --33 + j*(361) -339 + j*(-470) -238 + j*(311) -455 + j*(372) --419 + j*(47) --267 + j*(-6) -313 + j*(-315) --314 + j*(148) --167 + j*(-559) -371 + j*(-467) --377 + j*(337) -535 + j*(-262) -170 + j*(-213) --719 + j*(-409) --59 + j*(155) --137 + j*(240) --403 + j*(-211) --310 + j*(-119) -405 + j*(-72) --488 + j*(136) --270 + j*(-495) -375 + j*(-124) -294 + j*(-73) -494 + j*(406) -423 + j*(311) --401 + j*(-383) -378 + j*(293) --290 + j*(-348) -111 + j*(-182) -414 + j*(523) --121 + j*(746) -129 + j*(-466) -409 + j*(-359) -342 + j*(63) --325 + j*(174) --292 + j*(103) -221 + j*(407) -298 + j*(240) --343 + j*(363) -192 + j*(-296) --291 + j*(180) --76 + j*(-33) --58 + j*(-362) --260 + j*(-202) --301 + j*(-129) -86 + j*(400) --240 + j*(337) -77 + j*(-55) -279 + j*(831) -20 + j*(-13) -305 + j*(-124) -551 + j*(99) -439 + j*(438) --194 + j*(490) -592 + j*(216) --382 + j*(228) --316 + j*(76) -98 + j*(30) -216 + j*(-286) -268 + j*(18) --13 + j*(233) --497 + j*(-483) -25 + j*(-332) -168 + j*(227) -301 + j*(143) -73 + j*(-48) --3 + j*(-291) -588 + j*(16) -192 + j*(-489) -243 + j*(76) -254 + j*(539) --380 + j*(229) -489 + j*(15) -241 + j*(131) -158 + j*(-295) -306 + j*(195) --283 + j*(428) -412 + j*(-48) -384 + j*(-260) --188 + j*(38) --104 + j*(-159) -64 + j*(142) --39 + j*(92) --73 + j*(243) -114 + j*(-292) --19 + j*(36) --160 + j*(345) -123 + j*(-62) --45 + j*(297) -299 + j*(33) -117 + j*(-93) --214 + j*(44) --345 + j*(-15) --11 + j*(-78) -204 + j*(16) -132 + j*(-22) --45 + j*(59) --220 + j*(-21) -145 + j*(-76) --124 + j*(120) -156 + j*(-31) -21 + j*(-187) --81 + j*(160) --43 + j*(-79) -114 + j*(7) -247 + j*(-122) -90 + j*(96) --132 + j*(27) -228 + j*(11) --179 + j*(40) -78 + j*(89) --513 + j*(3) --152 + j*(246) --60 + j*(211) --108 + j*(-76) --30 + j*(-112) --68 + j*(-276) -18 + j*(42) --13 + j*(-322) --76 + j*(-78) -156 + j*(48) --25 + j*(121) -106 + j*(-127) --110 + j*(257) -263 + j*(132) --168 + j*(303) -18 + j*(271) -6 + j*(-148) -133 + j*(-263) --25 + j*(130) -71 + j*(329) -406 + j*(-14) --28 + j*(-89) --214 + j*(40) --121 + j*(194) --138 + j*(-7) -107 + j*(97) -213 + j*(-98) -114 + j*(73) --233 + j*(3) --34 + j*(290) -18 + j*(-125) --28 + j*(263) --121 + j*(12) -53 + j*(-48) -95 + j*(-21) --461 + j*(13) -213 + j*(110) -223 + j*(98) --137 + j*(-126) --167 + j*(30) --60 + j*(-438) -86 + j*(-72) -94 + j*(-175) --103 + j*(111) -93 + j*(57) --177 + j*(-207) --134 + j*(130) -194 + j*(159) -25 + j*(36) -25 + j*(-231) -134 + j*(7) -117 + j*(-178) --200 + j*(214) -11 + j*(51) --337 + j*(-10) -259 + j*(-6) --61 + j*(129) --28 + j*(39) --150 + j*(-81) -67 + j*(1) --139 + j*(144) --64 + j*(-216) -107 + j*(-387) --105 + j*(93) -342 + j*(-31) --133 + j*(26) -18 + j*(-242) --230 + j*(-160) --255 + j*(-103) -288 + j*(70) -45 + j*(18) -91 + j*(-15) -95 + j*(69) -6 + j*(193) --107 + j*(-19) -264 + j*(-83) -42 + j*(-170) --48 + j*(-8) -242 + j*(4) -320 + j*(47) --75 + j*(-93) --161 + j*(45) --58 + j*(-127) -112 + j*(66) -193 + j*(224) --577 + j*(-352) --33 + j*(142) -117 + j*(72) -1 + j*(-115) --107 + j*(167) --45 + j*(187) -29 + j*(-117) -108 + j*(-128) -103 + j*(226) --436 + j*(-210) --245 + j*(54) -37 + j*(-62) -1 + j*(-59) --233 + j*(82) --101 + j*(299) -74 + j*(46) -59 + j*(-214) --245 + j*(-179) -153 + j*(-385) --86 + j*(215) --105 + j*(-47) --48 + j*(-337) -51 + j*(153) -118 + j*(159) --117 + j*(-160) -131 + j*(19) -245 + j*(74) --171 + j*(86) --31 + j*(-61) --144 + j*(179) -35 + j*(-370) -170 + j*(-76) -280 + j*(-52) --89 + j*(-163) -78 + j*(47) --345 + j*(-32) --236 + j*(-15) -204 + j*(-49) --517 + j*(-52) --93 + j*(-81) -264 + j*(18) --144 + j*(-25) -212 + j*(121) -26 + j*(-342) -165 + j*(53) -41 + j*(-14) --111 + j*(197) --179 + j*(233) -121 + j*(255) -208 + j*(-71) -187 + j*(293) -110 + j*(-317) -118 + j*(225) -250 + j*(187) -4 + j*(-260) --48 + j*(72) --195 + j*(97) -91 + j*(-210) -113 + j*(-173) --32 + j*(2) --112 + j*(-9) -373 + j*(-229) -42 + j*(-64) --106 + j*(-13) --58 + j*(25) -68 + j*(89) --93 + j*(-106) -204 + j*(-76) --177 + j*(13) --84 + j*(-198) -168 + j*(287) --218 + j*(220) --139 + j*(-203) -346 + j*(156) --194 + j*(-30) -134 + j*(-30) --124 + j*(147) --199 + j*(-285) -168 + j*(-201) -122 + j*(-271) -103 + j*(-25) -40 + j*(-42) --129 + j*(42) -119 + j*(234) -91 + j*(185) -154 + j*(-153) -114 + j*(396) -103 + j*(156) --127 + j*(-274) -122 + j*(-151) -34 + j*(112) --236 + j*(-66) -266 + j*(-33) --177 + j*(-86) --26 + j*(-129) -52 + j*(164) --59 + j*(-304) --383 + j*(-279) -146 + j*(136) -419 + j*(40) --30 + j*(113) --105 + j*(142) -213 + j*(-259) -30 + j*(363) -168 + j*(-375) --107 + j*(60) -128 + j*(199) --71 + j*(113) --95 + j*(-124) --17 + j*(48) --57 + j*(65) --76 + j*(23) --274 + j*(-206) -125 + j*(276) -98 + j*(-57) --129 + j*(-179) --58 + j*(311) -54 + j*(52) --351 + j*(226) --252 + j*(55) --142 + j*(-17) -202 + j*(107) -176 + j*(-477) --71 + j*(18) --174 + j*(125) -144 + j*(-108) --10 + j*(-19) --28 + j*(112) --26 + j*(132) --236 + j*(-8) -37 + j*(-214) -111 + j*(216) -260 + j*(70) --30 + j*(-69) --91 + j*(157) -221 + j*(-96) --162 + j*(-126) --71 + j*(110) -16 + j*(117) -128 + j*(-4) -69 + j*(35) --62 + j*(177) -143 + j*(88) --124 + j*(-195) --118 + j*(-61) -26 + j*(-187) --76 + j*(262) --21 + j*(-103) --164 + j*(-139) --73 + j*(-175) -262 + j*(-58) -44 + j*(58) -78 + j*(-43) --245 + j*(336) --28 + j*(-38) --124 + j*(-168) --320 + j*(34) --175 + j*(-11) --190 + j*(-241) -119 + j*(-78) --242 + j*(264) --91 + j*(234) --57 + j*(-42) --189 + j*(11) -130 + j*(103) -217 + j*(-100) -170 + j*(-62) --327 + j*(82) --132 + j*(-118) -19 + j*(1) -15 + j*(-6) --479 + j*(69) -38 + j*(68) -1 + j*(-229) -93 + j*(-98) -54 + j*(-93) --23 + j*(-100) -1 + j*(-197) --269 + j*(-126) -177 + j*(23) --412 + j*(-282) --78 + j*(88) --214 + j*(225) --96 + j*(127) --40 + j*(181) -276 + j*(175) --191 + j*(-257) -163 + j*(-84) --82 + j*(92) -171 + j*(132) -213 + j*(-79) -234 + j*(125) --62 + j*(-272) -57 + j*(-56) -62 + j*(-363) --136 + j*(64) -40 + j*(33) --63 + j*(-95) --162 + j*(172) --141 + j*(-281) --13 + j*(40) -248 + j*(-70) --104 + j*(-439) -57 + j*(192) -21 + j*(16) --385 + j*(-86) -86 + j*(-322) --263 + j*(279) -238 + j*(83) -62 + j*(-112) --68 + j*(-26) -30 + j*(182) -6 + j*(-152) -100 + j*(-80) -91 + j*(1) --49 + j*(-240) -88 + j*(19) -74 + j*(98) -87 + j*(234) -5 + j*(-245) --310 + j*(57) --78 + j*(-243) --163 + j*(-32) -114 + j*(-437) -44 + j*(150) -158 + j*(-68) -327 + j*(-263) --3 + j*(-2) -151 + j*(268) --274 + j*(-351) --291 + j*(-420) --409 + j*(204) --454 + j*(-66) -66 + j*(26) --187 + j*(277) -73 + j*(-33) -118 + j*(123) -136 + j*(-40) -87 + j*(138) -264 + j*(47) -93 + j*(288) -113 + j*(107) --233 + j*(95) -19 + j*(170) --23 + j*(-486) -30 + j*(-47) -146 + j*(107) -177 + j*(226) --82 + j*(-301) -155 + j*(58) -78 + j*(-10) -390 + j*(233) --5 + j*(74) --33 + j*(25) --117 + j*(394) -202 + j*(-98) -18 + j*(83) -47 + j*(-127) -230 + j*(-156) -255 + j*(112) --26 + j*(358) -50 + j*(109) --56 + j*(-51) --78 + j*(-240) --190 + j*(42) -119 + j*(98) --146 + j*(84) --37 + j*(-115) -76 + j*(38) -99 + j*(-181) -31 + j*(-63) -69 + j*(61) --100 + j*(62) --81 + j*(161) -130 + j*(-101) -134 + j*(-168) -40 + j*(25) --57 + j*(-278) --58 + j*(244) --368 + j*(-64) -214 + j*(367) -43 + j*(104) -347 + j*(-150) -293 + j*(45) --139 + j*(-16) -198 + j*(120) -286 + j*(255) -342 + j*(-254) -70 + j*(-104) --275 + j*(-223) --37 + j*(-50) --337 + j*(-89) --74 + j*(-56) -133 + j*(202) --61 + j*(255) --209 + j*(-103) --110 + j*(-83) -130 + j*(244) --274 + j*(2) -78 + j*(-186) -56 + j*(163) --122 + j*(-139) -90 + j*(-124) --6 + j*(-28) -99 + j*(-203) --340 + j*(-146) -90 + j*(-62) -215 + j*(-257) -42 + j*(-3) -170 + j*(380) -2 + j*(62) --43 + j*(-52) --331 + j*(12) --26 + j*(33) -77 + j*(141) --184 + j*(-206) -349 + j*(74) -128 + j*(-83) --309 + j*(213) -233 + j*(22) -155 + j*(-16) --82 + j*(-190) --129 + j*(-1) -131 + j*(-341) -182 + j*(-120) -211 + j*(81) -47 + j*(-32) --79 + j*(233) --113 + j*(-443) -89 + j*(170) -218 + j*(-257) --78 + j*(74) --11 + j*(-57) --220 + j*(233) --165 + j*(62) -19 + j*(44) --121 + j*(-240) --3 + j*(-156) -272 + j*(11) --161 + j*(-361) --133 + j*(-153) --51 + j*(122) --30 + j*(56) --116 + j*(-74) -90 + j*(-298) -97 + j*(-151) -126 + j*(-69) -64 + j*(49) --18 + j*(-126) --45 + j*(-190) -72 + j*(-124) -42 + j*(-128) -238 + j*(-228) -18 + j*(-296) -182 + j*(188) -52 + j*(-131) --25 + j*(47) -66 + j*(-49) -327 + j*(-474) -110 + j*(71) --76 + j*(-78) -86 + j*(30) --158 + j*(221) --16 + j*(-371) --144 + j*(100) -9 + j*(197) --65 + j*(-11) --218 + j*(-257) -278 + j*(75) --103 + j*(40) -42 + j*(-145) -496 + j*(53) --161 + j*(-137) --82 + j*(-205) -116 + j*(-37) --134 + j*(98) --26 + j*(392) -221 + j*(-45) --209 + j*(-288) --261 + j*(96) -199 + j*(-429) -516 + j*(-110) -18 + j*(112) -106 + j*(-329) --83 + j*(-117) --190 + j*(36) -177 + j*(252) -13 + j*(15) -0 + j*(-269) -18 + j*(49) -262 + j*(17) --161 + j*(154) -71 + j*(-43) -274 + j*(-88) --167 + j*(67) -192 + j*(-173) --156 + j*(251) --127 + j*(31) -53 + j*(112) --47 + j*(306) --409 + j*(-194) -70 + j*(172) --108 + j*(-223) --54 + j*(6) -215 + j*(283) -281 + j*(-138) -53 + j*(102) -12 + j*(-93) -293 + j*(48) --223 + j*(-163) -37 + j*(127) --21 + j*(-30) -122 + j*(139) --6 + j*(147) --168 + j*(-25) --1 + j*(63) -203 + j*(-30) --184 + j*(-281) -0 + j*(-66) -245 + j*(80) --3 + j*(-154) --151 + j*(-327) --185 + j*(-123) -105 + j*(-202) --218 + j*(190) --54 + j*(29) -25 + j*(-47) --437 + j*(-132) --42 + j*(-11) --264 + j*(-191) --55 + j*(-18) -277 + j*(-223) -69 + j*(-213) --334 + j*(-90) -185 + j*(-269) --95 + j*(-21) --281 + j*(240) --86 + j*(132) --134 + j*(-120) -17 + j*(-402) --30 + j*(-4) -124 + j*(-308) --21 + j*(-54) -107 + j*(-12) -86 + j*(-109) -23 + j*(53) --42 + j*(-352) --68 + j*(-250) -354 + j*(-155) -34 + j*(-111) --156 + j*(228) -127 + j*(-209) -47 + j*(69) --118 + j*(298) -33 + j*(-36) -62 + j*(392) --269 + j*(-88) --366 + j*(-47) --127 + j*(-98) -91 + j*(40) --138 + j*(-253) --57 + j*(181) -186 + j*(-102) -83 + j*(-89) --9 + j*(-419) -109 + j*(265) -124 + j*(316) -12 + j*(-206) --10 + j*(153) --159 + j*(27) -53 + j*(-252) --21 + j*(168) -129 + j*(91) --205 + j*(-82) -85 + j*(143) --11 + j*(17) -71 + j*(-145) -45 + j*(80) -71 + j*(50) -180 + j*(49) -110 + j*(0) --60 + j*(233) -24 + j*(-153) --16 + j*(137) -269 + j*(187) --115 + j*(156) -29 + j*(81) --232 + j*(-161) -206 + j*(-56) --47 + j*(17) --18 + j*(-177) --100 + j*(126) --270 + j*(82) --180 + j*(42) -238 + j*(366) -69 + j*(236) -182 + j*(-151) -0 + j*(180) -232 + j*(-28) -72 + j*(299) -87 + j*(84) -35 + j*(-416) --200 + j*(-43) -206 + j*(-60) --245 + j*(-146) -89 + j*(95) --127 + j*(250) --342 + j*(-6) --5 + j*(342) --239 + j*(-119) -169 + j*(-29) --375 + j*(98) -81 + j*(-380) --65 + j*(4) --139 + j*(-205) -69 + j*(-94) --81 + j*(-175) -16 + j*(-124) --81 + j*(185) -165 + j*(378) --140 + j*(337) -42 + j*(91) --156 + j*(201) --127 + j*(-64) --35 + j*(-177) --238 + j*(-87) --241 + j*(-294) -88 + j*(-289) --164 + j*(56) --141 + j*(-109) -64 + j*(29) --239 + j*(-172) -88 + j*(-416) --188 + j*(-76) --222 + j*(103) -7 + j*(-53) -218 + j*(-284) -82 + j*(-288) -111 + j*(40) --47 + j*(111) --57 + j*(176) -20 + j*(-96) --25 + j*(284) --29 + j*(87) -63 + j*(266) --67 + j*(-129) -154 + j*(-69) -141 + j*(78) -38 + j*(-177) --46 + j*(-306) -271 + j*(125) -378 + j*(130) --303 + j*(-30) -148 + j*(-64) --124 + j*(-332) --153 + j*(71) --49 + j*(18) --78 + j*(-183) --334 + j*(-199) --238 + j*(-58) --269 + j*(-38) -253 + j*(-426) --166 + j*(197) -197 + j*(-147) --33 + j*(-86) -190 + j*(80) --111 + j*(-462) --76 + j*(-369) -501 + j*(-119) -192 + j*(-117) -106 + j*(-60) -148 + j*(-238) -10 + j*(79) -97 + j*(53) -64 + j*(-66) --162 + j*(-535) -60 + j*(83) --188 + j*(-98) -32 + j*(15) --74 + j*(-52) --30 + j*(-102) -61 + j*(300) --64 + j*(8) --245 + j*(105) -114 + j*(-330) -83 + j*(141) -98 + j*(98) --74 + j*(-268) -112 + j*(49) -451 + j*(-61) --107 + j*(52) -136 + j*(-39) --157 + j*(350) -33 + j*(-122) -258 + j*(173) -334 + j*(45) --48 + j*(170) -78 + j*(-82) -59 + j*(-108) -347 + j*(75) --314 + j*(86) --387 + j*(275) -6 + j*(132) --204 + j*(294) -124 + j*(98) --254 + j*(22) --89 + j*(-156) --392 + j*(-168) -141 + j*(-159) -201 + j*(-175) --28 + j*(5) -132 + j*(116) -4 + j*(-4) -227 + j*(-108) --268 + j*(-85) -115 + j*(-98) --57 + j*(139) -200 + j*(-103) --65 + j*(-194) --146 + j*(-59) --314 + j*(45) -146 + j*(-1) -26 + j*(40) --290 + j*(-56) --260 + j*(-264) -165 + j*(35) -235 + j*(-228) -149 + j*(-168) --25 + j*(-196) -33 + j*(-211) --172 + j*(-173) --148 + j*(168) --281 + j*(62) --56 + j*(-12) -179 + j*(-24) -54 + j*(45) --128 + j*(-153) -72 + j*(-62) --12 + j*(343) -214 + j*(-173) --105 + j*(41) -151 + j*(-11) --226 + j*(140) -24 + j*(175) --57 + j*(12) --25 + j*(86) --269 + j*(27) -175 + j*(13) -238 + j*(9) -107 + j*(62) -15 + j*(-73) -115 + j*(-37) -80 + j*(-197) --50 + j*(118) --206 + j*(123) -23 + j*(35) --257 + j*(-112) --66 + j*(183) --155 + j*(-4) --161 + j*(135) -132 + j*(-220) --22 + j*(-358) -197 + j*(277) -339 + j*(8) --232 + j*(-293) -134 + j*(-162) --253 + j*(179) --255 + j*(-197) --110 + j*(-202) --216 + j*(-243) --247 + j*(103) --16 + j*(-33) -107 + j*(-113) --93 + j*(-20) --52 + j*(299) --43 + j*(-234) --131 + j*(-33) -135 + j*(207) -88 + j*(-26) -125 + j*(206) -164 + j*(5) -78 + j*(-178) --151 + j*(-197) -190 + j*(-16) -151 + j*(88) --52 + j*(255) -19 + j*(-182) -144 + j*(-44) --16 + j*(-112) -145 + j*(81) --35 + j*(-1) --107 + j*(-6) -148 + j*(351) --156 + j*(421) --252 + j*(-71) -373 + j*(-182) -228 + j*(51) --71 + j*(137) -83 + j*(201) -54 + j*(-112) -26 + j*(-145) --55 + j*(4) -161 + j*(330) --30 + j*(-250) --421 + j*(-114) -30 + j*(-16) -69 + j*(106) --43 + j*(43) --155 + j*(178) -20 + j*(-208) --395 + j*(226) --147 + j*(129) -11 + j*(-42) --331 + j*(91) -81 + j*(56) --460 + j*(-49) --269 + j*(1) -19 + j*(216) --124 + j*(30) -16 + j*(190) --293 + j*(-240) --170 + j*(149) --101 + j*(95) -130 + j*(-82) --33 + j*(116) -28 + j*(21) -83 + j*(-83) --211 + j*(257) --6 + j*(133) -32 + j*(-163) -44 + j*(-69) -36 + j*(95) --80 + j*(24) --17 + j*(-354) -115 + j*(130) -28 + j*(-41) -287 + j*(195) -433 + j*(-71) --191 + j*(195) --75 + j*(-296) --195 + j*(170) -291 + j*(-35) --164 + j*(128) -271 + j*(50) -132 + j*(-71) -202 + j*(26) -12 + j*(-90) --260 + j*(25) -165 + j*(29) --89 + j*(250) --25 + j*(-21) --33 + j*(-4) -284 + j*(108) --162 + j*(-106) -76 + j*(-163) -85 + j*(70) --106 + j*(61) --273 + j*(32) -24 + j*(-115) -268 + j*(-297) --211 + j*(58) -243 + j*(16) -105 + j*(-155) --36 + j*(-225) -64 + j*(80) --42 + j*(31) -115 + j*(276) --332 + j*(-232) -111 + j*(7) --216 + j*(-134) --154 + j*(-279) --182 + j*(76) -121 + j*(-49) --88 + j*(-52) -167 + j*(-93) --135 + j*(-245) --210 + j*(405) --69 + j*(212) --48 + j*(-240) -385 + j*(306) -31 + j*(108) --7 + j*(-222) -30 + j*(-53) --194 + j*(-183) --21 + j*(57) --330 + j*(171) --42 + j*(-16) -199 + j*(221) --12 + j*(25) --70 + j*(458) --371 + j*(-155) --78 + j*(100) -49 + j*(-85) -110 + j*(-243) --23 + j*(40) -12 + j*(-71) --82 + j*(-624) --156 + j*(53) --153 + j*(264) -2 + j*(-132) -63 + j*(86) -133 + j*(40) -129 + j*(221) -192 + j*(-300) --122 + j*(202) -76 + j*(-155) -94 + j*(28) --17 + j*(281) --382 + j*(105) -310 + j*(158) -20 + j*(122) -211 + j*(-99) -217 + j*(-166) --1 + j*(-130) -32 + j*(-39) --64 + j*(-286) -365 + j*(-83) -216 + j*(89) -167 + j*(-338) -324 + j*(67) -223 + j*(123) -44 + j*(-21) -66 + j*(79) --109 + j*(105) -59 + j*(-62) -211 + j*(35) --165 + j*(-54) -142 + j*(123) --187 + j*(-115) -76 + j*(100) --290 + j*(-316) --78 + j*(162) -156 + j*(49) --69 + j*(-29) -202 + j*(151) -37 + j*(11) --40 + j*(-138) -31 + j*(10) --28 + j*(-112) --195 + j*(175) --178 + j*(187) -51 + j*(-35) -112 + j*(-6) --207 + j*(-35) --70 + j*(19) --129 + j*(-331) -99 + j*(-210) -275 + j*(123) --262 + j*(250) --9 + j*(129) -156 + j*(223) -59 + j*(42) --272 + j*(-320) --107 + j*(-27) --274 + j*(317) --271 + j*(238) -74 + j*(-22) -181 + j*(-249) -286 + j*(86) -57 + j*(268) --69 + j*(-50) -22 + j*(233) -137 + j*(168) -156 + j*(88) -250 + j*(165) -175 + j*(-258) --250 + j*(-158) --57 + j*(251) --192 + j*(98) -88 + j*(208) --175 + j*(130) -40 + j*(-162) --237 + j*(-4) -272 + j*(8) --54 + j*(163) -105 + j*(72) -216 + j*(-69) --257 + j*(139) --250 + j*(53) -30 + j*(-439) -78 + j*(-208) -182 + j*(177) -262 + j*(83) -318 + j*(-4) --6 + j*(214) --37 + j*(-172) --144 + j*(-33) --278 + j*(42) -195 + j*(29) -158 + j*(76) --30 + j*(-395) -189 + j*(-122) --165 + j*(-22) --307 + j*(240) -18 + j*(-73) -11 + j*(422) --108 + j*(-59) -366 + j*(13) --81 + j*(-116) --286 + j*(244) -99 + j*(349) --102 + j*(-100) --247 + j*(-32) -2 + j*(175) --40 + j*(337) -284 + j*(124) -107 + j*(-8) -126 + j*(107) --348 + j*(-184) -206 + j*(-15) -242 + j*(-8) -248 + j*(9) -83 + j*(65) --153 + j*(53) --117 + j*(169) --359 + j*(41) --34 + j*(3) --264 + j*(-237) -42 + j*(-223) -218 + j*(116) --92 + j*(-192) --259 + j*(-144) -304 + j*(78) --10 + j*(337) -8 + j*(122) --57 + j*(28) --35 + j*(37) --46 + j*(13) -55 + j*(261) --244 + j*(-163) -42 + j*(-45) --339 + j*(-79) -82 + j*(412) -7 + j*(150) -132 + j*(199) -137 + j*(-323) -269 + j*(-166) --7 + j*(54) --243 + j*(232) --180 + j*(-30) --78 + j*(-49) --113 + j*(4) -30 + j*(-32) -95 + j*(64) --1 + j*(-146) -20 + j*(-11) -91 + j*(194) -51 + j*(-269) --250 + j*(-105) --141 + j*(-33) --114 + j*(310) -177 + j*(211) --138 + j*(417) --13 + j*(258) -260 + j*(-113) -47 + j*(169) -11 + j*(-429) --204 + j*(-11) --370 + j*(33) -401 + j*(-77) -74 + j*(186) -322 + j*(146) -57 + j*(-364) -18 + j*(-114) -171 + j*(-362) --86 + j*(66) -11 + j*(-148) --72 + j*(190) -185 + j*(-168) --73 + j*(-161) -182 + j*(18) --256 + j*(-304) --103 + j*(21) --41 + j*(358) --136 + j*(132) --18 + j*(-144) -267 + j*(102) -76 + j*(146) --5 + j*(-34) --105 + j*(29) --261 + j*(-179) --86 + j*(63) -106 + j*(280) --15 + j*(-155) -144 + j*(-52) --55 + j*(-344) -156 + j*(-20) -161 + j*(-242) -163 + j*(-223) --354 + j*(64) --5 + j*(-21) -20 + j*(-246) -210 + j*(-316) -396 + j*(-194) -16 + j*(225) --228 + j*(165) -46 + j*(21) --43 + j*(-298) --129 + j*(-132) --201 + j*(77) --32 + j*(21) --37 + j*(107) --16 + j*(94) -18 + j*(-93) -207 + j*(-175) -88 + j*(226) -216 + j*(-142) --170 + j*(102) -21 + j*(-291) -119 + j*(-173) --236 + j*(-33) -49 + j*(302) --151 + j*(136) --284 + j*(-181) -286 + j*(39) --70 + j*(160) --56 + j*(122) -5 + j*(320) --34 + j*(-181) --272 + j*(83) -33 + j*(-203) --248 + j*(-199) -146 + j*(255) --190 + j*(28) --60 + j*(-340) -13 + j*(-252) -134 + j*(269) -130 + j*(-115) -137 + j*(-25) -292 + j*(141) -171 + j*(82) -14 + j*(49) -11 + j*(23) --257 + j*(124) --130 + j*(-160) --247 + j*(164) --13 + j*(168) --62 + j*(-258) --11 + j*(-66) -291 + j*(274) -42 + j*(224) --135 + j*(266) --109 + j*(47) --37 + j*(-110) -84 + j*(-120) --73 + j*(322) --52 + j*(33) --139 + j*(24) -42 + j*(-132) -41 + j*(259) --45 + j*(165) -248 + j*(-201) --334 + j*(-131) --92 + j*(154) -202 + j*(7) -88 + j*(154) --100 + j*(42) --251 + j*(9) -129 + j*(-116) --187 + j*(82) -134 + j*(-412) --271 + j*(-181) --137 + j*(-20) --57 + j*(79) -136 + j*(95) -81 + j*(157) --100 + j*(107) --235 + j*(233) -117 + j*(-72) -388 + j*(-156) --147 + j*(-264) -0 + j*(-124) --18 + j*(156) --119 + j*(-114) --334 + j*(144) -206 + j*(303) -181 + j*(84) --198 + j*(-121) --146 + j*(91) --49 + j*(-77) -313 + j*(148) --241 + j*(57) -33 + j*(11) -161 + j*(-20) --76 + j*(158) -51 + j*(28) --106 + j*(67) --6 + j*(-136) --172 + j*(-97) -77 + j*(112) -0 + j*(59) -34 + j*(-29) -276 + j*(-67) --209 + j*(-214) -21 + j*(-59) -19 + j*(23) -35 + j*(-177) --221 + j*(242) -49 + j*(-40) -291 + j*(248) -220 + j*(57) --193 + j*(65) -129 + j*(101) --36 + j*(-160) --431 + j*(-53) --78 + j*(-492) -147 + j*(-326) --260 + j*(-37) -322 + j*(-134) --202 + j*(-203) -58 + j*(40) -45 + j*(-83) --66 + j*(-205) --130 + j*(-68) -122 + j*(47) -124 + j*(-115) --37 + j*(281) --276 + j*(-77) --188 + j*(379) -195 + j*(-42) --4 + j*(110) --288 + j*(-63) -1 + j*(-96) -69 + j*(-42) -100 + j*(173) --129 + j*(246) -311 + j*(-30) --71 + j*(-151) --368 + j*(-41) --347 + j*(190) --173 + j*(-92) --170 + j*(224) --40 + j*(-163) --103 + j*(90) -373 + j*(301) --206 + j*(55) --8 + j*(-184) -30 + j*(-18) --184 + j*(15) --132 + j*(103) -69 + j*(88) --115 + j*(-293) --318 + j*(124) -250 + j*(284) -33 + j*(-127) -193 + j*(317) --72 + j*(242) --32 + j*(122) --214 + j*(277) -78 + j*(-18) --173 + j*(-41) --135 + j*(-180) --31 + j*(-104) --22 + j*(278) -52 + j*(-16) -204 + j*(-62) --30 + j*(-24) -171 + j*(-48) --54 + j*(-339) --84 + j*(91) --95 + j*(-288) -40 + j*(-330) --115 + j*(16) --451 + j*(-48) -119 + j*(99) --36 + j*(135) -200 + j*(144) -127 + j*(-43) -252 + j*(91) -105 + j*(218) -29 + j*(176) -139 + j*(-190) --108 + j*(-139) -144 + j*(-76) -120 + j*(214) -47 + j*(228) --42 + j*(-4) -279 + j*(3) --140 + j*(-100) --16 + j*(49) --148 + j*(-21) -102 + j*(-150) --48 + j*(-264) --204 + j*(-53) -207 + j*(81) --272 + j*(-115) --28 + j*(-252) --61 + j*(-4) --114 + j*(116) -64 + j*(182) -131 + j*(101) -117 + j*(-1) -148 + j*(-296) -99 + j*(248) -112 + j*(-18) -198 + j*(306) --63 + j*(13) --226 + j*(-149) -93 + j*(121) --233 + j*(140) --156 + j*(-279) --182 + j*(-107) --117 + j*(-240) --209 + j*(36) -32 + j*(-31) -257 + j*(-126) --320 + j*(94) -25 + j*(-454) --35 + j*(81) --132 + j*(170) --161 + j*(230) -365 + j*(304) --53 + j*(-175) -101 + j*(165) -242 + j*(301) -113 + j*(190) -164 + j*(-160) -25 + j*(-512) -343 + j*(31) --228 + j*(4) -185 + j*(-76) --13 + j*(272) -69 + j*(6) -45 + j*(-23) -3 + j*(135) --240 + j*(-105) -124 + j*(143) --40 + j*(-218) --35 + j*(-109) --23 + j*(-3) --96 + j*(-139) -93 + j*(240) --193 + j*(-181) --45 + j*(80) -165 + j*(-144) --176 + j*(-94) --85 + j*(-242) --100 + j*(-11) --73 + j*(181) --6 + j*(-151) -98 + j*(109) --223 + j*(101) --279 + j*(58) -81 + j*(86) -14 + j*(102) -56 + j*(-215) --228 + j*(-92) --165 + j*(-62) -262 + j*(52) --40 + j*(-160) --183 + j*(-139) -226 + j*(-66) --107 + j*(184) -115 + j*(-64) --129 + j*(139) -90 + j*(-296) --88 + j*(-1) --81 + j*(-83) -78 + j*(-35) -68 + j*(-37) --86 + j*(-149) --1 + j*(84) --124 + j*(-24) --319 + j*(-315) --105 + j*(-221) --185 + j*(77) --211 + j*(28) --58 + j*(-169) -59 + j*(-424) -97 + j*(222) --82 + j*(216) -170 + j*(-109) -185 + j*(6) --328 + j*(202) --128 + j*(-71) --34 + j*(-259) -23 + j*(409) --218 + j*(55) -55 + j*(-269) --49 + j*(368) -62 + j*(131) -15 + j*(29) -79 + j*(349) -9 + j*(-190) --188 + j*(232) -194 + j*(153) -74 + j*(291) --152 + j*(119) -148 + j*(-206) --110 + j*(-170) -194 + j*(-139) -113 + j*(-100) --209 + j*(-302) -2 + j*(64) --128 + j*(-59) -13 + j*(-122) -7 + j*(-200) -25 + j*(-101) -104 + j*(-127) -168 + j*(-125) -93 + j*(-216) --91 + j*(-49) --179 + j*(-68) --95 + j*(117) -267 + j*(-81) --48 + j*(-41) --122 + j*(-340) --91 + j*(216) -104 + j*(142) --69 + j*(-206) --82 + j*(-101) --93 + j*(136) -6 + j*(-57) --51 + j*(-202) -53 + j*(-167) --127 + j*(-216) --292 + j*(-243) -170 + j*(-228) --241 + j*(-90) --132 + j*(-216) --81 + j*(-295) --40 + j*(96) --180 + j*(-167) --404 + j*(42) --64 + j*(-373) --190 + j*(100) -75 + j*(-219) -430 + j*(219) --23 + j*(-146) --93 + j*(25) -18 + j*(257) --28 + j*(303) --209 + j*(261) -748 + j*(271) -177 + j*(154) -352 + j*(577) --202 + j*(-223) --177 + j*(11) -327 + j*(256) -346 + j*(-228) --372 + j*(398) -354 + j*(666) -399 + j*(-1) -406 + j*(-42) -105 + j*(-37) --281 + j*(523) --76 + j*(-529) -675 + j*(81) --245 + j*(418) -333 + j*(275) --395 + j*(136) --63 + j*(338) --166 + j*(-158) --139 + j*(-445) --238 + j*(407) --342 + j*(-115) --323 + j*(101) --547 + j*(289) -329 + j*(117) --255 + j*(-172) -375 + j*(-109) --52 + j*(-234) -643 + j*(-313) --18 + j*(258) -11 + j*(168) --12 + j*(15) -351 + j*(-247) --199 + j*(334) -387 + j*(21) --126 + j*(63) --375 + j*(263) -23 + j*(206) -31 + j*(261) --211 + j*(334) -633 + j*(210) --194 + j*(-467) -335 + j*(-243) -368 + j*(-135) -542 + j*(-241) --190 + j*(-300) --18 + j*(-262) -279 + j*(-42) --548 + j*(-407) -107 + j*(-480) -318 + j*(274) --220 + j*(-252) -142 + j*(66) --156 + j*(290) --474 + j*(320) -602 + j*(255) --226 + j*(187) --403 + j*(-288) --443 + j*(-303) -159 + j*(-513) --480 + j*(-58) -263 + j*(-127) --346 + j*(537) -187 + j*(-350) --146 + j*(336) --175 + j*(-127) -250 + j*(532) -317 + j*(173) --38 + j*(-279) -339 + j*(-542) -168 + j*(-103) -606 + j*(-121) -128 + j*(-260) -132 + j*(-116) -487 + j*(497) --177 + j*(-310) --281 + j*(-375) --33 + j*(-250) --459 + j*(37) -13 + j*(-3) -206 + j*(-288) -167 + j*(-218) -225 + j*(163) --460 + j*(-350) --422 + j*(-256) --273 + j*(-288) -145 + j*(-539) -264 + j*(675) --177 + j*(-416) --278 + j*(92) -256 + j*(93) --11 + j*(122) -119 + j*(205) -264 + j*(-350) -267 + j*(320) -628 + j*(115) --300 + j*(206) --256 + j*(127) -46 + j*(644) --257 + j*(174) -397 + j*(-358) -437 + j*(-221) --404 + j*(-392) --453 + j*(-234) -211 + j*(-168) --473 + j*(-173) -378 + j*(297) -206 + j*(280) --203 + j*(-341) --251 + j*(-229) -173 + j*(-60) --311 + j*(-156) -1 + j*(134) --24 + j*(-322) --291 + j*(-203) --424 + j*(127) -134 + j*(-62) --295 + j*(-141) --380 + j*(-233) --83 + j*(320) --169 + j*(171) --419 + j*(263) -219 + j*(-126) --227 + j*(221) --533 + j*(-33) -139 + j*(162) --259 + j*(81) --77 + j*(-316) --334 + j*(368) -78 + j*(-279) --127 + j*(-14) -186 + j*(-54) --317 + j*(-562) -127 + j*(424) -23 + j*(241) --170 + j*(-218) -533 + j*(511) --530 + j*(-110) --246 + j*(576) -151 + j*(-443) -38 + j*(358) --462 + j*(-40) --293 + j*(386) -403 + j*(404) -465 + j*(126) --39 + j*(220) -546 + j*(-482) -187 + j*(267) --166 + j*(-417) -293 + j*(-158) -190 + j*(-276) -291 + j*(-456) --256 + j*(177) -236 + j*(83) --21 + j*(566) --309 + j*(-536) --276 + j*(274) -291 + j*(30) -316 + j*(480) -471 + j*(114) --284 + j*(197) -344 + j*(-291) --263 + j*(-347) -81 + j*(33) --381 + j*(-364) -49 + j*(-97) -300 + j*(516) -303 + j*(-48) -192 + j*(499) -115 + j*(-372) -387 + j*(-398) -264 + j*(2) --104 + j*(286) -643 + j*(-144) -327 + j*(447) -33 + j*(-457) --221 + j*(-59) --251 + j*(37) -300 + j*(4) -245 + j*(77) --199 + j*(-344) --103 + j*(16) --275 + j*(596) -226 + j*(-307) --321 + j*(379) -151 + j*(237) -403 + j*(-258) -292 + j*(-358) -728 + j*(378) -204 + j*(601) --392 + j*(-49) -205 + j*(56) --96 + j*(143) --361 + j*(270) -132 + j*(159) -342 + j*(156) -171 + j*(262) -252 + j*(55) -205 + j*(-261) -272 + j*(-192) -225 + j*(139) --375 + j*(241) --179 + j*(325) --121 + j*(-150) -178 + j*(-279) -532 + j*(-95) --397 + j*(361) -149 + j*(-227) --253 + j*(-415) --622 + j*(-208) --309 + j*(369) -305 + j*(361) -224 + j*(394) -385 + j*(617) --238 + j*(-120) -524 + j*(-277) --209 + j*(-190) -387 + j*(658) -405 + j*(211) -45 + j*(333) --313 + j*(137) --313 + j*(-31) -492 + j*(320) -138 + j*(-307) --240 + j*(364) -316 + j*(204) -177 + j*(-408) -204 + j*(-63) -358 + j*(-165) --47 + j*(-238) -425 + j*(361) -596 + j*(-56) -409 + j*(-180) --61 + j*(-536) --389 + j*(262) --337 + j*(-270) --185 + j*(-47) --414 + j*(-222) -394 + j*(200) -102 + j*(201) --581 + j*(-57) -312 + j*(118) -284 + j*(421) -171 + j*(242) -385 + j*(-218) -119 + j*(166) -408 + j*(484) -215 + j*(188) -269 + j*(434) -8 + j*(337) --308 + j*(514) -366 + j*(-49) -167 + j*(-166) -638 + j*(185) -344 + j*(-203) --331 + j*(174) -315 + j*(-16) -264 + j*(-185) --389 + j*(382) --76 + j*(-346) -284 + j*(221) -216 + j*(309) --296 + j*(-339) --290 + j*(89) -341 + j*(400) -126 + j*(-108) -267 + j*(288) --211 + j*(177) -355 + j*(-21) -522 + j*(255) -268 + j*(-234) -436 + j*(392) -703 + j*(57) --435 + j*(-436) -284 + j*(-130) --115 + j*(-286) --614 + j*(-284) --152 + j*(-368) -219 + j*(-30) -313 + j*(-261) --134 + j*(-260) --55 + j*(-498) --254 + j*(291) -196 + j*(-122) -318 + j*(334) --264 + j*(366) -13 + j*(-230) -314 + j*(609) -241 + j*(-139) --88 + j*(347) -323 + j*(-305) --443 + j*(-257) --231 + j*(300) --424 + j*(479) -320 + j*(543) -23 + j*(-188) --392 + j*(22) --497 + j*(93) --218 + j*(-392) --286 + j*(-441) --263 + j*(-591) --153 + j*(-87) --125 + j*(204) --385 + j*(54) -92 + j*(269) --45 + j*(46) --571 + j*(-607) --372 + j*(122) --384 + j*(19) -193 + j*(258) --22 + j*(377) --268 + j*(331) --184 + j*(425) -554 + j*(-243) --146 + j*(490) --168 + j*(-530) -180 + j*(38) --352 + j*(25) --334 + j*(57) --215 + j*(188) -57 + j*(89) -196 + j*(182) -397 + j*(491) --361 + j*(-99) -214 + j*(161) --84 + j*(346) -112 + j*(364) --244 + j*(346) --320 + j*(79) -406 + j*(93) --196 + j*(-371) -158 + j*(-298) -82 + j*(189) --342 + j*(-235) -202 + j*(-280) --194 + j*(-349) --197 + j*(-312) --291 + j*(-99) --171 + j*(283) -87 + j*(-41) --266 + j*(92) -595 + j*(573) --362 + j*(-139) -154 + j*(-235) -127 + j*(-603) -191 + j*(663) -387 + j*(-70) -275 + j*(505) -161 + j*(-393) -411 + j*(-243) --258 + j*(366) --273 + j*(35) --436 + j*(-470) -472 + j*(62) --401 + j*(75) -99 + j*(-165) -180 + j*(421) -270 + j*(-199) --52 + j*(-218) --260 + j*(-283) --527 + j*(277) --286 + j*(456) --444 + j*(97) --276 + j*(309) -132 + j*(-304) --231 + j*(-378) --245 + j*(153) -406 + j*(305) --338 + j*(229) -163 + j*(180) --281 + j*(290) -477 + j*(-118) --377 + j*(457) -169 + j*(-161) --347 + j*(-248) -291 + j*(-45) --157 + j*(60) -124 + j*(227) --281 + j*(-433) -513 + j*(-282) -333 + j*(235) -299 + j*(-273) -322 + j*(211) -391 + j*(402) -198 + j*(-60) --58 + j*(-472) -559 + j*(125) -130 + j*(334) --93 + j*(245) -471 + j*(-211) -93 + j*(276) -36 + j*(-378) -780 + j*(281) --291 + j*(301) -286 + j*(334) -227 + j*(-363) -351 + j*(163) -194 + j*(98) --512 + j*(317) --47 + j*(197) --325 + j*(393) -122 + j*(9) --264 + j*(-231) -339 + j*(141) --274 + j*(-426) -330 + j*(-318) -625 + j*(-276) --372 + j*(406) --253 + j*(-171) --314 + j*(-271) -159 + j*(161) -264 + j*(-505) --280 + j*(563) -326 + j*(3) -235 + j*(78) -66 + j*(-384) -368 + j*(156) --227 + j*(-17) --409 + j*(-381) --252 + j*(-306) -108 + j*(218) --433 + j*(-35) -16 + j*(23) -648 + j*(-353) -296 + j*(47) --291 + j*(360) -408 + j*(-459) -530 + j*(156) -175 + j*(262) -8 + j*(-363) -57 + j*(221) -142 + j*(161) --162 + j*(72) -185 + j*(-160) -280 + j*(-128) --272 + j*(-232) -31 + j*(-88) --626 + j*(-132) -122 + j*(-325) --274 + j*(126) --312 + j*(206) -231 + j*(37) --261 + j*(-124) -86 + j*(450) --328 + j*(-586) --175 + j*(-283) -25 + j*(-170) -340 + j*(372) -385 + j*(181) -354 + j*(-480) --204 + j*(30) --368 + j*(273) --315 + j*(204) --453 + j*(269) --433 + j*(173) -532 + j*(258) -351 + j*(-124) --26 + j*(-1) -208 + j*(83) -84 + j*(141) --620 + j*(-32) --229 + j*(34) --146 + j*(-315) --143 + j*(-223) --135 + j*(375) -421 + j*(345) -498 + j*(-307) -425 + j*(-670) -315 + j*(613) --361 + j*(253) -470 + j*(-390) --8 + j*(132) --173 + j*(74) --375 + j*(317) -278 + j*(-225) --247 + j*(156) --371 + j*(-346) --366 + j*(-146) -417 + j*(-374) -27 + j*(-231) -462 + j*(311) --147 + j*(385) -433 + j*(-363) --347 + j*(-521) --345 + j*(206) --503 + j*(473) -238 + j*(-395) -159 + j*(-239) --163 + j*(189) --468 + j*(-154) --351 + j*(-30) --271 + j*(491) -277 + j*(94) --4 + j*(-162) -331 + j*(-389) --246 + j*(496) -165 + j*(330) -453 + j*(257) --64 + j*(-125) --544 + j*(-247) -135 + j*(-176) --383 + j*(-524) --16 + j*(693) --104 + j*(189) -139 + j*(110) -525 + j*(236) -172 + j*(-342) -313 + j*(223) -307 + j*(-435) --525 + j*(-231) -317 + j*(-317) --525 + j*(-696) -245 + j*(-131) --568 + j*(-351) -71 + j*(-274) --57 + j*(95) --313 + j*(-417) -250 + j*(-74) -338 + j*(-238) -270 + j*(-151) --166 + j*(437) --414 + j*(460) --285 + j*(304) --274 + j*(511) -408 + j*(-422) -25 + j*(-37) --370 + j*(107) -367 + j*(146) --135 + j*(-324) --329 + j*(180) -163 + j*(-82) --568 + j*(185) --496 + j*(-288) --416 + j*(-366) -37 + j*(-95) -70 + j*(-424) -88 + j*(38) --277 + j*(87) --44 + j*(404) --184 + j*(-651) --304 + j*(-487) --301 + j*(-136) --36 + j*(-501) -416 + j*(104) -130 + j*(-443) -127 + j*(-177) -387 + j*(-144) --186 + j*(6) --333 + j*(-57) --101 + j*(-190) -450 + j*(161) -85 + j*(-147) -442 + j*(-466) --52 + j*(-173) -45 + j*(13) -289 + j*(96) -148 + j*(461) --49 + j*(330) --6 + j*(-279) --44 + j*(152) -279 + j*(-176) -404 + j*(178) -239 + j*(297) --267 + j*(449) --371 + j*(-45) --206 + j*(-267) -144 + j*(-57) --352 + j*(199) -249 + j*(472) --87 + j*(136) --147 + j*(-480) -442 + j*(397) --30 + j*(129) --322 + j*(417) -818 + j*(11) --14 + j*(338) --257 + j*(-72) -352 + j*(-235) --411 + j*(82) -348 + j*(-66) -50 + j*(257) --315 + j*(103) --394 + j*(-30) --274 + j*(336) --436 + j*(-178) --147 + j*(-202) -173 + j*(264) --167 + j*(-347) --430 + j*(-67) -229 + j*(-447) --255 + j*(771) -29 + j*(-579) -412 + j*(208) -385 + j*(-573) --523 + j*(-310) --513 + j*(-223) -148 + j*(-237) --70 + j*(127) --346 + j*(12) --245 + j*(-208) --146 + j*(204) --216 + j*(23) -4 + j*(87) --163 + j*(274) --146 + j*(-27) --74 + j*(250) --97 + j*(69) -18 + j*(85) --33 + j*(-192) --84 + j*(-299) -15 + j*(32) -182 + j*(-194) -30 + j*(-209) --151 + j*(-126) -315 + j*(-103) --146 + j*(-21) -79 + j*(168) -535 + j*(44) -169 + j*(-331) --139 + j*(229) --192 + j*(55) --84 + j*(-47) -221 + j*(78) --83 + j*(-228) -86 + j*(-13) --165 + j*(58) --315 + j*(72) --57 + j*(-23) -16 + j*(-209) --50 + j*(-103) --206 + j*(-19) -36 + j*(-36) --78 + j*(-187) --224 + j*(173) -172 + j*(29) -284 + j*(66) -155 + j*(194) -14 + j*(28) -144 + j*(-105) --102 + j*(-113) --132 + j*(-83) -15 + j*(-325) -40 + j*(-86) -203 + j*(-185) -64 + j*(115) -427 + j*(-47) -20 + j*(40) --71 + j*(127) -238 + j*(44) -112 + j*(-142) -39 + j*(-171) -122 + j*(-204) -62 + j*(-64) --33 + j*(-149) --170 + j*(106) -296 + j*(52) -332 + j*(279) -203 + j*(70) -286 + j*(76) --206 + j*(42) --11 + j*(298) -129 + j*(-209) -110 + j*(218) --17 + j*(-75) -198 + j*(15) -153 + j*(256) --6 + j*(-125) -71 + j*(-89) -64 + j*(-11) -80 + j*(-31) -192 + j*(112) --196 + j*(-18) --21 + j*(204) --54 + j*(305) -10 + j*(292) -30 + j*(238) --144 + j*(333) --230 + j*(-60) --354 + j*(76) -87 + j*(-45) -193 + j*(215) --170 + j*(204) -143 + j*(93) --206 + j*(231) -151 + j*(121) -323 + j*(-74) --132 + j*(-209) --150 + j*(-150) --153 + j*(-82) --243 + j*(-144) -310 + j*(95) -342 + j*(-61) --155 + j*(-117) -357 + j*(66) --360 + j*(119) -86 + j*(-33) -209 + j*(40) --105 + j*(62) -163 + j*(43) --58 + j*(56) -134 + j*(-247) -14 + j*(84) --105 + j*(-28) --193 + j*(-215) --51 + j*(-180) -97 + j*(-98) --116 + j*(-25) -422 + j*(107) -105 + j*(62) --30 + j*(62) -255 + j*(141) --247 + j*(240) -23 + j*(25) --163 + j*(6) -0 + j*(308) --115 + j*(-250) --83 + j*(-33) --345 + j*(-57) -495 + j*(-29) -148 + j*(-51) --203 + j*(144) --57 + j*(39) --52 + j*(283) --7 + j*(218) -300 + j*(-182) -274 + j*(202) -59 + j*(13) --74 + j*(259) -300 + j*(28) -1 + j*(117) -151 + j*(242) -267 + j*(332) -57 + j*(-315) -38 + j*(-178) -65 + j*(8) --144 + j*(-271) -213 + j*(-199) -151 + j*(-91) --252 + j*(-130) --93 + j*(-66) -74 + j*(69) --118 + j*(110) -293 + j*(187) -124 + j*(84) -211 + j*(-75) --40 + j*(-15) -123 + j*(28) -105 + j*(-295) -198 + j*(185) -76 + j*(74) --236 + j*(203) --81 + j*(1) --135 + j*(73) --333 + j*(-332) -46 + j*(64) --37 + j*(233) --17 + j*(37) -321 + j*(182) -146 + j*(307) -98 + j*(-2) --191 + j*(-138) --252 + j*(124) -168 + j*(-105) -28 + j*(343) --59 + j*(-71) --119 + j*(-351) -18 + j*(-82) -319 + j*(69) -140 + j*(-41) -278 + j*(301) --142 + j*(166) --189 + j*(-316) -173 + j*(-260) --26 + j*(-151) --94 + j*(-54) -10 + j*(23) -134 + j*(-170) --45 + j*(-260) -138 + j*(-59) -79 + j*(-220) -2 + j*(102) -163 + j*(74) --105 + j*(42) --295 + j*(-200) -184 + j*(-141) --216 + j*(246) --66 + j*(-23) -185 + j*(86) --378 + j*(146) --137 + j*(250) -233 + j*(190) --66 + j*(-220) --30 + j*(-128) -332 + j*(-71) -293 + j*(-6) --35 + j*(-1) --58 + j*(247) -252 + j*(-73) --75 + j*(-220) --57 + j*(6) --197 + j*(-8) -321 + j*(149) --308 + j*(141) -146 + j*(-230) --168 + j*(-322) --315 + j*(-190) -120 + j*(-298) -155 + j*(-344) --15 + j*(146) --156 + j*(-192) --91 + j*(-6) --62 + j*(-40) --40 + j*(109) --256 + j*(-19) -118 + j*(-350) --365 + j*(-211) --68 + j*(-100) --86 + j*(-320) -33 + j*(-34) -136 + j*(1) -7 + j*(430) -161 + j*(54) -30 + j*(-78) --87 + j*(-162) -282 + j*(269) --277 + j*(260) --10 + j*(404) -245 + j*(134) --96 + j*(-129) --183 + j*(83) --114 + j*(266) --3 + j*(-74) -115 + j*(77) -141 + j*(31) --105 + j*(50) --20 + j*(-341) -148 + j*(-116) -388 + j*(-106) --112 + j*(-20) -58 + j*(-6) -207 + j*(-138) -124 + j*(-84) --174 + j*(71) --79 + j*(321) --153 + j*(48) --171 + j*(-315) --115 + j*(19) --73 + j*(-77) --2 + j*(-59) -71 + j*(-69) -13 + j*(1) -129 + j*(-286) --316 + j*(162) -303 + j*(210) -32 + j*(136) --199 + j*(85) --248 + j*(169) -246 + j*(88) -309 + j*(-105) -83 + j*(-149) --46 + j*(-25) --194 + j*(-202) --88 + j*(-108) -76 + j*(29) -79 + j*(-213) --90 + j*(14) --88 + j*(106) --194 + j*(-71) --57 + j*(42) --478 + j*(-83) -269 + j*(-33) -180 + j*(25) --47 + j*(-96) --190 + j*(115) --10 + j*(-342) --144 + j*(-26) --264 + j*(4) --192 + j*(48) --303 + j*(117) --49 + j*(268) -95 + j*(-177) -419 + j*(69) --131 + j*(156) --170 + j*(-4) --8 + j*(-139) --42 + j*(185) -0 + j*(-301) -20 + j*(-200) -397 + j*(-147) --130 + j*(-238) --42 + j*(33) --78 + j*(12) --59 + j*(-111) --206 + j*(-145) --141 + j*(-148) --94 + j*(-163) -146 + j*(-16) -43 + j*(211) -202 + j*(244) --67 + j*(-282) -223 + j*(64) -65 + j*(194) --76 + j*(-1) -14 + j*(240) --51 + j*(136) --23 + j*(165) --44 + j*(64) -110 + j*(132) --153 + j*(-107) --20 + j*(-114) --226 + j*(-141) --103 + j*(4) --113 + j*(211) -153 + j*(-9) -252 + j*(-18) --115 + j*(-216) --83 + j*(295) -165 + j*(47) -66 + j*(-152) -194 + j*(88) --46 + j*(-30) -100 + j*(-37) -148 + j*(-224) -167 + j*(84) --174 + j*(-62) --333 + j*(-233) -250 + j*(-173) -325 + j*(-9) -36 + j*(-29) --85 + j*(20) -141 + j*(179) --13 + j*(15) --179 + j*(-415) --358 + j*(87) --236 + j*(236) -291 + j*(-188) --114 + j*(268) --187 + j*(-233) -62 + j*(-151) --139 + j*(-336) -301 + j*(-37) --75 + j*(74) -12 + j*(-259) --351 + j*(-17) -193 + j*(-151) --4 + j*(105) -206 + j*(5) --153 + j*(-107) -185 + j*(242) --5 + j*(-105) -20 + j*(14) -36 + j*(368) -37 + j*(139) -11 + j*(-123) --218 + j*(-71) --122 + j*(86) --95 + j*(95) --412 + j*(-148) --218 + j*(-69) --326 + j*(-87) --131 + j*(11) --11 + j*(84) -98 + j*(-194) --49 + j*(-99) -207 + j*(-170) --200 + j*(-292) --46 + j*(152) --144 + j*(-54) -196 + j*(268) -100 + j*(31) --132 + j*(157) --95 + j*(-239) -185 + j*(-6) --117 + j*(-161) -106 + j*(164) -122 + j*(48) --47 + j*(45) -47 + j*(83) -195 + j*(361) -68 + j*(207) -43 + j*(17) --120 + j*(-76) -1 + j*(-81) --138 + j*(-8) -1 + j*(-15) -10 + j*(-10) -30 + j*(37) --24 + j*(-55) --235 + j*(251) --16 + j*(236) -139 + j*(-286) -62 + j*(86) -183 + j*(-165) --71 + j*(-117) -57 + j*(-56) -71 + j*(-23) --518 + j*(52) -189 + j*(-45) -3 + j*(-190) -89 + j*(186) -36 + j*(-11) --308 + j*(283) -153 + j*(-55) -170 + j*(68) -16 + j*(-214) -141 + j*(223) -13 + j*(163) --99 + j*(197) --350 + j*(-84) -361 + j*(-123) --153 + j*(-35) -184 + j*(-101) --250 + j*(104) --256 + j*(147) --56 + j*(166) --67 + j*(-78) -1 + j*(-257) --173 + j*(-69) --109 + j*(-93) --17 + j*(71) -243 + j*(-110) -54 + j*(166) --80 + j*(-250) --134 + j*(-32) --169 + j*(-201) --98 + j*(-239) -339 + j*(-90) --11 + j*(-78) -25 + j*(45) -109 + j*(-8) -45 + j*(-274) --215 + j*(-130) --139 + j*(178) -213 + j*(-269) --202 + j*(-202) --221 + j*(-17) -219 + j*(-466) -87 + j*(-278) -358 + j*(-91) -5 + j*(169) --129 + j*(330) -42 + j*(0) --86 + j*(-29) --80 + j*(295) --154 + j*(-121) -76 + j*(233) -238 + j*(-31) -97 + j*(-160) -23 + j*(-81) -5 + j*(-187) --39 + j*(-139) --262 + j*(83) -128 + j*(23) --274 + j*(-51) -229 + j*(-56) -127 + j*(486) -104 + j*(112) --46 + j*(257) --210 + j*(-244) -81 + j*(111) -112 + j*(198) -231 + j*(319) --86 + j*(103) --7 + j*(-55) --6 + j*(-153) -139 + j*(141) -37 + j*(212) -56 + j*(346) -298 + j*(-73) --4 + j*(-55) -163 + j*(36) --46 + j*(229) -124 + j*(-144) --156 + j*(122) --209 + j*(-109) -117 + j*(-151) --235 + j*(-193) --38 + j*(-64) -136 + j*(28) -66 + j*(-388) --102 + j*(101) -171 + j*(182) --192 + j*(81) -251 + j*(-343) -261 + j*(-61) -88 + j*(-33) --158 + j*(408) -305 + j*(-63) --8 + j*(-103) -565 + j*(250) --128 + j*(-51) --211 + j*(-122) --115 + j*(170) -42 + j*(-29) --99 + j*(-112) --30 + j*(-85) -232 + j*(213) -282 + j*(-5) --86 + j*(113) --300 + j*(-236) --132 + j*(-146) --4 + j*(93) -99 + j*(215) --70 + j*(-24) --95 + j*(23) --104 + j*(-33) -237 + j*(-209) -190 + j*(-75) -15 + j*(73) -106 + j*(86) -3 + j*(-178) -148 + j*(-86) -105 + j*(209) -34 + j*(-276) -10 + j*(204) -135 + j*(-187) --57 + j*(-210) -69 + j*(93) --7 + j*(487) --141 + j*(-340) -33 + j*(13) -106 + j*(-265) -51 + j*(105) --247 + j*(-185) --168 + j*(-27) --46 + j*(-325) -79 + j*(139) --74 + j*(535) -245 + j*(-96) -334 + j*(-317) --103 + j*(159) --204 + j*(-19) -144 + j*(239) -36 + j*(-187) -98 + j*(-91) --249 + j*(-33) -9 + j*(-223) -326 + j*(-165) --135 + j*(-42) --125 + j*(-16) -15 + j*(-2) --243 + j*(-287) --33 + j*(182) --91 + j*(15) --81 + j*(-71) --194 + j*(-63) -37 + j*(-23) --138 + j*(-11) --54 + j*(100) -50 + j*(31) --43 + j*(115) --36 + j*(-128) -153 + j*(-170) -23 + j*(-226) --72 + j*(13) -130 + j*(-53) --259 + j*(93) --315 + j*(-78) --141 + j*(-96) -241 + j*(112) --54 + j*(159) -58 + j*(57) --355 + j*(63) -307 + j*(-132) -192 + j*(88) --240 + j*(15) --35 + j*(-6) -123 + j*(291) --161 + j*(158) -34 + j*(-92) -36 + j*(233) -302 + j*(-199) -71 + j*(56) --144 + j*(91) -131 + j*(276) --77 + j*(151) --110 + j*(214) -12 + j*(-490) --186 + j*(-77) -308 + j*(84) --203 + j*(3) -113 + j*(-112) --222 + j*(-176) -81 + j*(-112) -15 + j*(-14) --50 + j*(-186) -144 + j*(-47) --120 + j*(-125) -215 + j*(207) --32 + j*(-16) --383 + j*(247) --96 + j*(81) --148 + j*(-11) -48 + j*(148) -173 + j*(0) -79 + j*(390) -180 + j*(-223) -274 + j*(40) --153 + j*(47) --116 + j*(112) -121 + j*(255) -198 + j*(176) -74 + j*(134) --170 + j*(168) -91 + j*(129) -105 + j*(-324) --326 + j*(25) --109 + j*(74) -174 + j*(-59) --244 + j*(54) --314 + j*(279) --145 + j*(213) -238 + j*(103) -28 + j*(190) -46 + j*(-172) --28 + j*(-190) --122 + j*(-110) --112 + j*(-82) -298 + j*(-21) --171 + j*(83) -99 + j*(16) -143 + j*(71) --141 + j*(-247) --214 + j*(-83) --9 + j*(14) --66 + j*(-51) --175 + j*(-115) -233 + j*(-421) -117 + j*(54) -148 + j*(-204) --122 + j*(128) --4 + j*(20) --139 + j*(-47) -105 + j*(-64) -21 + j*(-56) --144 + j*(-13) --238 + j*(-225) --97 + j*(139) --83 + j*(15) -45 + j*(80) --1 + j*(173) -260 + j*(141) --125 + j*(2) -117 + j*(100) -100 + j*(-3) -255 + j*(-33) --214 + j*(-199) -243 + j*(344) -85 + j*(158) --322 + j*(-165) --214 + j*(296) --128 + j*(58) --74 + j*(-222) --25 + j*(-93) -44 + j*(5) --63 + j*(-137) --160 + j*(-328) -29 + j*(12) --78 + j*(107) -142 + j*(238) -205 + j*(-250) --207 + j*(191) -165 + j*(-142) -199 + j*(141) -28 + j*(-93) --141 + j*(175) --177 + j*(148) -274 + j*(-18) --224 + j*(-92) -17 + j*(-247) -265 + j*(-45) --121 + j*(134) --66 + j*(-78) -253 + j*(-176) --52 + j*(86) --156 + j*(13) --239 + j*(-81) -51 + j*(-115) --134 + j*(36) --83 + j*(-69) --117 + j*(78) -145 + j*(91) -288 + j*(114) -6 + j*(136) -121 + j*(240) --60 + j*(37) -197 + j*(100) --275 + j*(78) -57 + j*(321) --260 + j*(170) -91 + j*(-288) --168 + j*(-164) --171 + j*(-35) --136 + j*(344) -43 + j*(3) --206 + j*(168) --343 + j*(124) --222 + j*(-301) -98 + j*(146) --30 + j*(-252) -203 + j*(-21) --42 + j*(-90) -49 + j*(-36) --62 + j*(-53) --202 + j*(103) -2 + j*(53) -95 + j*(297) -67 + j*(-303) -183 + j*(-70) --399 + j*(74) --272 + j*(-213) --167 + j*(158) -68 + j*(-21) --180 + j*(77) -25 + j*(-18) --57 + j*(-4) -136 + j*(-37) -215 + j*(-322) -322 + j*(34) --122 + j*(-172) -185 + j*(264) --144 + j*(247) -5 + j*(-125) -36 + j*(-313) -189 + j*(5) -140 + j*(-150) -7 + j*(69) --113 + j*(11) -190 + j*(368) --284 + j*(-105) --62 + j*(5) --132 + j*(-367) --225 + j*(-90) -50 + j*(-269) -134 + j*(243) --141 + j*(-52) --226 + j*(53) -342 + j*(-53) -93 + j*(-263) --92 + j*(-141) -125 + j*(162) --123 + j*(66) -42 + j*(49) --93 + j*(-114) --92 + j*(-310) --271 + j*(-95) -114 + j*(-197) -322 + j*(158) --43 + j*(28) --215 + j*(-171) -173 + j*(204) -332 + j*(213) -94 + j*(67) -328 + j*(23) -392 + j*(-35) -155 + j*(-135) -3 + j*(315) --211 + j*(50) -226 + j*(-136) --25 + j*(-26) --126 + j*(78) --107 + j*(-45) -24 + j*(227) --100 + j*(100) -260 + j*(22) --76 + j*(390) --288 + j*(49) -66 + j*(110) --163 + j*(-91) --273 + j*(-385) -28 + j*(-218) --231 + j*(156) -47 + j*(-76) -75 + j*(-82) --43 + j*(133) -3 + j*(-226) --69 + j*(-83) -231 + j*(-101) --290 + j*(-52) -47 + j*(57) --200 + j*(89) --70 + j*(265) -55 + j*(-255) --156 + j*(127) -91 + j*(337) --3 + j*(163) --129 + j*(-339) --16 + j*(167) --245 + j*(291) --114 + j*(168) --84 + j*(-148) --7 + j*(-243) --47 + j*(-44) -166 + j*(50) -227 + j*(-92) -215 + j*(291) -149 + j*(35) --109 + j*(-145) --190 + j*(-100) --102 + j*(-8) -230 + j*(169) -16 + j*(58) -133 + j*(-169) --16 + j*(291) -267 + j*(72) -84 + j*(52) --342 + j*(73) --101 + j*(228) --16 + j*(180) --2 + j*(122) -3 + j*(-344) --93 + j*(-185) -38 + j*(92) -226 + j*(71) -390 + j*(-98) -179 + j*(-201) --180 + j*(-31) --40 + j*(-165) -109 + j*(-119) -105 + j*(-171) --322 + j*(313) --1 + j*(-18) --47 + j*(256) -282 + j*(-29) --383 + j*(-225) -284 + j*(16) -81 + j*(244) -252 + j*(279) -257 + j*(-23) --491 + j*(254) --102 + j*(175) --46 + j*(269) -102 + j*(91) -5 + j*(123) -55 + j*(69) -29 + j*(105) --197 + j*(4) --84 + j*(226) --12 + j*(95) --57 + j*(-259) -195 + j*(-243) -134 + j*(133) -25 + j*(-165) --71 + j*(-205) -91 + j*(-71) --201 + j*(18) --135 + j*(-405) -180 + j*(153) -323 + j*(276) -376 + j*(73) -221 + j*(65) --231 + j*(236) -164 + j*(156) -238 + j*(97) --18 + j*(-199) -144 + j*(-33) --231 + j*(33) --23 + j*(154) -50 + j*(24) --145 + j*(-113) -32 + j*(138) -110 + j*(-121) -168 + j*(-242) -233 + j*(20) -30 + j*(87) -115 + j*(-67) -221 + j*(-12) -23 + j*(64) -66 + j*(161) --91 + j*(-159) --98 + j*(158) --73 + j*(49) --74 + j*(-26) --209 + j*(76) -280 + j*(88) -1 + j*(-30) -474 + j*(136) --39 + j*(-202) -61 + j*(-49) --82 + j*(-31) --25 + j*(267) -110 + j*(286) --257 + j*(-42) -288 + j*(-35) -16 + j*(324) -449 + j*(-50) --169 + j*(190) -108 + j*(-13) --151 + j*(33) --21 + j*(119) -82 + j*(-81) -132 + j*(-28) --413 + j*(-19) --295 + j*(-208) -153 + j*(145) --7 + j*(194) --110 + j*(-147) --145 + j*(-126) -284 + j*(64) --81 + j*(110) -263 + j*(-72) -12 + j*(-312) --76 + j*(119) -154 + j*(52) -138 + j*(109) --98 + j*(-220) --433 + j*(-9) -267 + j*(-3) --168 + j*(203) -33 + j*(-329) -129 + j*(-35) --177 + j*(-58) --161 + j*(-55) --161 + j*(108) --168 + j*(320) --258 + j*(65) --165 + j*(30) --131 + j*(-6) --98 + j*(25) -136 + j*(410) -1 + j*(332) -6 + j*(117) --42 + j*(-151) --15 + j*(-139) -292 + j*(-97) -208 + j*(-216) -113 + j*(-93) -168 + j*(160) --261 + j*(88) -226 + j*(110) -70 + j*(-298) --221 + j*(312) -54 + j*(101) --108 + j*(166) -306 + j*(162) -75 + j*(52) --129 + j*(-223) -47 + j*(59) -235 + j*(75) --226 + j*(45) -238 + j*(91) -324 + j*(168) -132 + j*(-354) --504 + j*(151) -234 + j*(112) -236 + j*(179) --25 + j*(-47) -136 + j*(-141) -311 + j*(352) -20 + j*(-145) -61 + j*(-187) -146 + j*(-66) --111 + j*(-25) -238 + j*(-6) --248 + j*(-57) -255 + j*(169) -368 + j*(-76) -13 + j*(7) --101 + j*(33) -1 + j*(227) --243 + j*(-105) --4 + j*(59) -118 + j*(38) --23 + j*(57) -85 + j*(-116) --170 + j*(-131) --13 + j*(-11) -49 + j*(-61) --37 + j*(294) -118 + j*(308) --120 + j*(-21) --232 + j*(-107) -393 + j*(312) -25 + j*(76) -74 + j*(23) -59 + j*(-136) -306 + j*(86) --260 + j*(-314) -194 + j*(163) --199 + j*(257) --175 + j*(-257) --232 + j*(13) -240 + j*(-95) --155 + j*(-172) -361 + j*(-116) --132 + j*(-152) --110 + j*(71) --279 + j*(288) --4 + j*(-28) --12 + j*(154) -89 + j*(190) -104 + j*(42) --221 + j*(-151) --91 + j*(115) -162 + j*(-30) --471 + j*(-45) -225 + j*(-34) -161 + j*(199) -136 + j*(164) --116 + j*(87) --48 + j*(195) -74 + j*(156) --23 + j*(7) -204 + j*(166) --150 + j*(1) -19 + j*(79) -44 + j*(5) --161 + j*(76) -122 + j*(-240) -151 + j*(-18) --23 + j*(53) --227 + j*(97) --26 + j*(-221) --358 + j*(-142) -217 + j*(-240) --139 + j*(-170) -39 + j*(202) -55 + j*(-36) -122 + j*(-217) -65 + j*(242) -23 + j*(13) --46 + j*(-73) --81 + j*(-328) -131 + j*(-276) --136 + j*(186) -158 + j*(204) -100 + j*(-209) -35 + j*(43) -4 + j*(43) --263 + j*(6) --16 + j*(159) -316 + j*(139) -336 + j*(-135) --201 + j*(-235) --13 + j*(-197) -275 + j*(139) --188 + j*(13) --152 + j*(-9) --61 + j*(-177) --369 + j*(-195) -160 + j*(-98) -56 + j*(-1) --276 + j*(-13) -112 + j*(-183) --231 + j*(206) -42 + j*(-163) -76 + j*(-34) -25 + j*(-84) -62 + j*(-61) --258 + j*(-87) --145 + j*(169) --240 + j*(289) --204 + j*(-272) --191 + j*(-68) -45 + j*(91) --124 + j*(46) --261 + j*(-18) -144 + j*(340) --24 + j*(216) --7 + j*(-41) -239 + j*(52) --292 + j*(-157) -210 + j*(-414) --299 + j*(-11) -6 + j*(71) -226 + j*(-406) -27 + j*(187) --72 + j*(-43) --115 + j*(-215) -41 + j*(-39) -220 + j*(38) --158 + j*(-246) --24 + j*(-111) --69 + j*(126) -137 + j*(-32) --279 + j*(11) --98 + j*(-329) --38 + j*(68) --366 + j*(19) --94 + j*(-104) -197 + j*(-37) --93 + j*(34) --352 + j*(-19) -64 + j*(40) -165 + j*(-195) -37 + j*(42) --177 + j*(-74) --194 + j*(-129) -269 + j*(174) -55 + j*(-28) --56 + j*(-37) --309 + j*(-131) -69 + j*(-18) --173 + j*(-9) -122 + j*(-270) -64 + j*(-221) -197 + j*(66) --66 + j*(354) -1 + j*(133) --125 + j*(129) --255 + j*(-137) -180 + j*(106) --223 + j*(385) -335 + j*(42) --99 + j*(-32) -182 + j*(91) -213 + j*(29) -32 + j*(-33) --75 + j*(37) --109 + j*(-296) -134 + j*(99) --53 + j*(-76) -140 + j*(176) -248 + j*(-379) --76 + j*(-151) --132 + j*(-22) --116 + j*(110) --82 + j*(-76) --199 + j*(-174) -118 + j*(240) --144 + j*(13) --25 + j*(173) --230 + j*(-95) -125 + j*(182) --105 + j*(122) --101 + j*(195) -20 + j*(-121) -35 + j*(-342) --119 + j*(-385) --188 + j*(-165) --252 + j*(-393) --269 + j*(-127) --31 + j*(-12) -336 + j*(-78) --52 + j*(-105) --25 + j*(330) -11 + j*(149) --81 + j*(-163) --153 + j*(-223) -107 + j*(-33) --294 + j*(-106) --189 + j*(247) --218 + j*(-154) -99 + j*(-35) -127 + j*(-290) -404 + j*(-88) --135 + j*(268) -316 + j*(313) -206 + j*(161) --385 + j*(36) --17 + j*(266) -4 + j*(-23) --83 + j*(73) -0 + j*(116) -160 + j*(199) -178 + j*(-109) --69 + j*(-147) -125 + j*(59) -244 + j*(98) --146 + j*(197) -59 + j*(234) -218 + j*(386) -23 + j*(-74) -438 + j*(90) -259 + j*(55) -181 + j*(214) --38 + j*(-76) --182 + j*(55) --148 + j*(-138) --130 + j*(281) -125 + j*(-132) --90 + j*(-105) -183 + j*(255) --138 + j*(288) --165 + j*(-25) --207 + j*(427) -259 + j*(-175) -147 + j*(-359) -116 + j*(-28) --263 + j*(-146) --217 + j*(48) -9 + j*(-62) -77 + j*(-11) -61 + j*(-215) -35 + j*(66) -85 + j*(1) -6 + j*(-23) -161 + j*(37) --124 + j*(280) -111 + j*(-3) -26 + j*(233) --76 + j*(130) -15 + j*(-241) --78 + j*(-167) -44 + j*(-25) --167 + j*(205) --99 + j*(-188) --154 + j*(120) --61 + j*(11) -361 + j*(-10) -236 + j*(-204) -139 + j*(-104) --106 + j*(44) --40 + j*(99) --1 + j*(-134) --148 + j*(30) --134 + j*(54) --239 + j*(85) --275 + j*(-269) -90 + j*(-83) --225 + j*(-148) -332 + j*(-88) --47 + j*(424) --128 + j*(78) -163 + j*(69) --175 + j*(88) --146 + j*(243) -308 + j*(25) -301 + j*(26) -110 + j*(-218) --139 + j*(-78) -279 + j*(92) -161 + j*(252) --91 + j*(81) --100 + j*(11) --90 + j*(92) --98 + j*(-146) -404 + j*(216) -178 + j*(-197) --50 + j*(-149) -165 + j*(-58) -27 + j*(-303) -95 + j*(169) --108 + j*(52) -294 + j*(-26) --37 + j*(-3) --101 + j*(-292) -187 + j*(250) --71 + j*(339) -42 + j*(-67) --66 + j*(50) --37 + j*(-90) -93 + j*(56) -141 + j*(-18) -77 + j*(-32) -74 + j*(28) -248 + j*(223) -232 + j*(-345) -66 + j*(-51) -42 + j*(49) -54 + j*(113) -25 + j*(-40) --88 + j*(156) -52 + j*(-112) --214 + j*(325) -144 + j*(122) --170 + j*(147) --251 + j*(33) --195 + j*(-218) -433 + j*(224) --174 + j*(-269) --75 + j*(-378) --30 + j*(-155) -227 + j*(-212) --1 + j*(-420) --45 + j*(331) -139 + j*(-228) -114 + j*(438) -313 + j*(-54) --460 + j*(-39) -125 + j*(-170) -222 + j*(-85) --127 + j*(-302) -97 + j*(279) -114 + j*(121) --226 + j*(144) -69 + j*(10) -162 + j*(-109) -206 + j*(-395) --243 + j*(-5) --86 + j*(294) -15 + j*(68) -206 + j*(-216) --190 + j*(151) --88 + j*(-41) -44 + j*(202) --36 + j*(-110) --35 + j*(16) --29 + j*(85) -0 + j*(155) --35 + j*(-83) -221 + j*(-148) -18 + j*(-342) --83 + j*(7) --8 + j*(-144) -9 + j*(-88) --103 + j*(-317) -191 + j*(187) --337 + j*(-266) --24 + j*(8) --515 + j*(-130) --129 + j*(142) -78 + j*(138) --70 + j*(264) -117 + j*(-196) -214 + j*(263) -45 + j*(-140) -127 + j*(-354) --16 + j*(-46) --6 + j*(-17) --69 + j*(-194) -8 + j*(315) -52 + j*(119) -243 + j*(65) -19 + j*(1) --163 + j*(-174) -124 + j*(-188) --438 + j*(25) -102 + j*(-9) -88 + j*(-352) -214 + j*(-132) -150 + j*(-23) --28 + j*(58) -52 + j*(-147) --59 + j*(332) --248 + j*(88) -47 + j*(138) -210 + j*(-60) -129 + j*(-173) --54 + j*(235) --190 + j*(284) --74 + j*(142) -73 + j*(-128) --46 + j*(-215) -126 + j*(328) --136 + j*(105) --32 + j*(-168) --313 + j*(-133) -59 + j*(-33) --39 + j*(158) -93 + j*(-158) --30 + j*(-192) -119 + j*(21) --8 + j*(180) -177 + j*(-231) -211 + j*(-264) -98 + j*(146) -46 + j*(13) --170 + j*(98) -93 + j*(18) --115 + j*(-21) --86 + j*(-20) -76 + j*(325) -77 + j*(33) -199 + j*(-40) -154 + j*(-236) --14 + j*(139) -37 + j*(65) --121 + j*(36) --206 + j*(247) --18 + j*(65) -573 + j*(148) -169 + j*(-257) --64 + j*(40) -53 + j*(-59) --46 + j*(88) --197 + j*(176) -18 + j*(-134) --177 + j*(-109) --76 + j*(142) -252 + j*(-144) --2 + j*(-101) -41 + j*(-153) --109 + j*(-24) -4 + j*(141) -49 + j*(-73) --151 + j*(134) --125 + j*(151) --78 + j*(272) -49 + j*(-177) --193 + j*(-143) --164 + j*(-261) -29 + j*(-115) -195 + j*(-140) -85 + j*(13) --86 + j*(27) --77 + j*(-128) -378 + j*(114) --436 + j*(49) --55 + j*(134) --144 + j*(-27) -99 + j*(315) -92 + j*(154) -148 + j*(177) -93 + j*(83) -119 + j*(310) -190 + j*(-248) --259 + j*(-248) -218 + j*(310) -63 + j*(197) -226 + j*(81) -22 + j*(-151) -60 + j*(-168) --285 + j*(231) --40 + j*(-78) -144 + j*(-128) --20 + j*(-402) -66 + j*(-8) --71 + j*(17) -94 + j*(-111) --22 + j*(-16) -128 + j*(-156) --212 + j*(324) --320 + j*(409) --137 + j*(235) -52 + j*(-438) -205 + j*(178) -86 + j*(-149) -246 + j*(-124) -129 + j*(-48) --23 + j*(72) -54 + j*(-18) --136 + j*(225) --134 + j*(198) -255 + j*(-239) --378 + j*(-39) --23 + j*(110) -35 + j*(-124) -47 + j*(-40) -177 + j*(-16) -178 + j*(-54) --197 + j*(33) -141 + j*(-42) -134 + j*(245) -68 + j*(101) --353 + j*(-16) --375 + j*(47) -129 + j*(-129) --75 + j*(-96) -192 + j*(66) -116 + j*(41) --33 + j*(17) -103 + j*(81) --52 + j*(214) -132 + j*(59) --342 + j*(375) --308 + j*(-103) --68 + j*(140) -460 + j*(110) --18 + j*(-97) -551 + j*(-522) -243 + j*(69) -534 + j*(264) --373 + j*(-374) --543 + j*(503) -292 + j*(223) -494 + j*(-12) --96 + j*(-122) -600 + j*(-210) -378 + j*(-357) -39 + j*(477) -298 + j*(82) --46 + j*(604) --197 + j*(28) --313 + j*(460) --57 + j*(168) -368 + j*(-167) --82 + j*(-532) -12 + j*(-259) --498 + j*(-542) -567 + j*(190) -18 + j*(-402) -675 + j*(32) --188 + j*(272) -778 + j*(51) -245 + j*(479) --82 + j*(-250) -342 + j*(-177) -360 + j*(-356) -279 + j*(286) --396 + j*(-656) -154 + j*(-335) --88 + j*(-243) -327 + j*(-137) -488 + j*(274) -322 + j*(-62) --43 + j*(507) -660 + j*(265) --264 + j*(81) --158 + j*(-299) --449 + j*(-491) -557 + j*(78) --6 + j*(-75) -569 + j*(135) -478 + j*(-146) --92 + j*(-381) --289 + j*(170) -276 + j*(-35) --373 + j*(-409) --288 + j*(-107) -173 + j*(-235) -286 + j*(-235) -236 + j*(-559) -52 + j*(164) --2 + j*(-477) -169 + j*(346) --322 + j*(-5) --154 + j*(151) -250 + j*(66) --477 + j*(79) -281 + j*(-82) -214 + j*(-72) -188 + j*(394) -146 + j*(-163) --297 + j*(292) -133 + j*(-588) -648 + j*(-378) -285 + j*(453) -377 + j*(-400) -441 + j*(349) -388 + j*(-69) -396 + j*(550) --27 + j*(-142) -446 + j*(361) -255 + j*(-25) -138 + j*(-252) -443 + j*(162) -471 + j*(-293) -309 + j*(359) -187 + j*(178) -359 + j*(-255) --251 + j*(292) --246 + j*(-288) --402 + j*(427) -77 + j*(211) --254 + j*(364) -123 + j*(-347) --223 + j*(-178) --245 + j*(-308) -392 + j*(192) --302 + j*(453) --384 + j*(-284) --161 + j*(-283) -117 + j*(-281) --272 + j*(274) --211 + j*(249) --530 + j*(-353) -204 + j*(471) -23 + j*(-124) --119 + j*(-276) --35 + j*(-373) -443 + j*(-426) --23 + j*(-441) -149 + j*(-441) --160 + j*(335) -224 + j*(-366) --166 + j*(81) -30 + j*(-435) -213 + j*(-171) -337 + j*(364) --301 + j*(121) -163 + j*(358) --417 + j*(255) --170 + j*(-19) -198 + j*(-239) -418 + j*(-470) -187 + j*(225) --338 + j*(-273) --581 + j*(87) -167 + j*(-600) --685 + j*(414) -351 + j*(-370) -6 + j*(-515) --279 + j*(-240) -45 + j*(-40) --130 + j*(233) --637 + j*(-235) --187 + j*(165) --135 + j*(386) -16 + j*(355) --219 + j*(8) -469 + j*(-107) -71 + j*(108) --16 + j*(15) --14 + j*(-530) --252 + j*(68) -288 + j*(536) -288 + j*(-182) --478 + j*(-6) --134 + j*(151) --38 + j*(-388) --414 + j*(-317) -440 + j*(-426) --218 + j*(-705) --304 + j*(-85) --662 + j*(54) -273 + j*(-4) -268 + j*(211) -18 + j*(315) -141 + j*(292) -116 + j*(268) --253 + j*(146) -235 + j*(-55) --259 + j*(-178) --197 + j*(-585) --64 + j*(441) --271 + j*(-188) -358 + j*(506) -13 + j*(-94) --339 + j*(-167) -329 + j*(400) -50 + j*(-484) -91 + j*(366) --407 + j*(-144) --439 + j*(165) -170 + j*(-325) --479 + j*(355) -237 + j*(-239) -99 + j*(-355) --122 + j*(281) -515 + j*(148) --132 + j*(-269) --174 + j*(34) -11 + j*(-386) -291 + j*(-351) -243 + j*(52) --300 + j*(129) -344 + j*(-442) --232 + j*(83) --10 + j*(2) -300 + j*(733) --139 + j*(28) -83 + j*(-425) --403 + j*(-188) --344 + j*(-337) -345 + j*(144) --245 + j*(-193) --552 + j*(105) -433 + j*(-513) -426 + j*(188) -12 + j*(385) --114 + j*(-211) --261 + j*(-512) -268 + j*(139) -327 + j*(305) -309 + j*(-86) -366 + j*(407) --206 + j*(277) --81 + j*(319) --21 + j*(108) -33 + j*(-84) -234 + j*(349) --337 + j*(759) -169 + j*(324) --183 + j*(333) -1 + j*(-487) -156 + j*(-346) -240 + j*(-270) -224 + j*(-426) --71 + j*(-328) -117 + j*(-204) -79 + j*(-344) --361 + j*(113) --165 + j*(332) --582 + j*(-463) -504 + j*(204) --578 + j*(139) --26 + j*(209) --121 + j*(378) --511 + j*(55) -156 + j*(-371) -12 + j*(-390) -231 + j*(-57) -11 + j*(-35) --498 + j*(-8) --465 + j*(-315) --45 + j*(-214) -245 + j*(53) --460 + j*(-199) --151 + j*(272) --453 + j*(-342) -194 + j*(8) --68 + j*(-393) --231 + j*(168) --364 + j*(-337) --414 + j*(-211) -701 + j*(-303) --287 + j*(-534) -201 + j*(140) -177 + j*(110) --54 + j*(-180) --344 + j*(-205) -280 + j*(53) -432 + j*(-19) -376 + j*(99) -363 + j*(509) -404 + j*(-474) --279 + j*(28) --496 + j*(74) -308 + j*(-384) -680 + j*(230) -620 + j*(-209) -295 + j*(444) -194 + j*(411) --185 + j*(-2) -546 + j*(317) --5 + j*(313) --415 + j*(229) -188 + j*(429) -247 + j*(617) --12 + j*(495) -175 + j*(312) --170 + j*(-268) --74 + j*(-233) --162 + j*(-310) --210 + j*(156) -395 + j*(-435) --184 + j*(268) --24 + j*(-264) -431 + j*(-350) --389 + j*(453) --98 + j*(-118) -117 + j*(531) --165 + j*(358) -74 + j*(-362) --304 + j*(61) --199 + j*(158) -228 + j*(167) -397 + j*(170) -266 + j*(-310) -450 + j*(93) --215 + j*(-63) --231 + j*(-31) -411 + j*(-336) -443 + j*(173) -288 + j*(240) -70 + j*(208) --298 + j*(-249) -349 + j*(279) --82 + j*(-6) --282 + j*(-40) -227 + j*(-322) -93 + j*(695) --433 + j*(392) -65 + j*(-356) --249 + j*(250) -297 + j*(-205) -107 + j*(363) -95 + j*(270) -310 + j*(-12) --228 + j*(532) -111 + j*(78) -227 + j*(-24) -141 + j*(-596) --252 + j*(409) --277 + j*(-249) --53 + j*(532) --173 + j*(-244) -519 + j*(402) -18 + j*(234) --135 + j*(307) --309 + j*(95) --289 + j*(264) -289 + j*(-284) -147 + j*(-311) --377 + j*(460) --298 + j*(549) -177 + j*(332) -599 + j*(-378) -40 + j*(355) -373 + j*(121) --266 + j*(-45) --85 + j*(-47) --186 + j*(-18) --8 + j*(-195) -409 + j*(-610) -34 + j*(502) --576 + j*(78) -298 + j*(164) -409 + j*(-331) -506 + j*(-433) -460 + j*(-700) --84 + j*(269) --303 + j*(375) --5 + j*(-106) -30 + j*(85) -296 + j*(361) --179 + j*(-178) --477 + j*(-308) --141 + j*(-696) --149 + j*(398) -392 + j*(431) --300 + j*(206) --248 + j*(515) -462 + j*(217) -253 + j*(244) -164 + j*(-196) -308 + j*(-40) -28 + j*(124) --172 + j*(-233) -471 + j*(-272) -332 + j*(445) --217 + j*(200) --307 + j*(-209) -503 + j*(207) -499 + j*(378) --203 + j*(87) --273 + j*(438) -170 + j*(364) -384 + j*(-122) -291 + j*(-509) --74 + j*(422) --571 + j*(126) -76 + j*(264) --383 + j*(-128) -333 + j*(-436) --105 + j*(-313) -260 + j*(-61) -404 + j*(465) --172 + j*(363) --225 + j*(-317) -185 + j*(-140) -132 + j*(40) --199 + j*(-365) -470 + j*(-37) -89 + j*(-250) --94 + j*(256) -0 + j*(397) --326 + j*(531) --245 + j*(-2) --105 + j*(-4) -100 + j*(274) --392 + j*(-227) --274 + j*(173) --93 + j*(-418) -646 + j*(214) --568 + j*(-668) -582 + j*(16) --129 + j*(-274) -272 + j*(226) --8 + j*(-176) -351 + j*(387) -467 + j*(194) --225 + j*(166) --40 + j*(-489) -82 + j*(-408) --168 + j*(268) --28 + j*(-298) --503 + j*(-358) -94 + j*(-250) -564 + j*(41) --468 + j*(-158) -331 + j*(311) -303 + j*(-211) -185 + j*(-366) --262 + j*(171) --165 + j*(-372) --414 + j*(-305) --334 + j*(-371) --62 + j*(26) -141 + j*(208) -250 + j*(347) --256 + j*(-16) --501 + j*(552) -452 + j*(-195) --239 + j*(-151) --426 + j*(-532) -10 + j*(-282) --412 + j*(414) --482 + j*(-233) --321 + j*(256) --124 + j*(32) -409 + j*(-373) --568 + j*(-613) --311 + j*(306) --81 + j*(-678) -432 + j*(-555) --374 + j*(376) -231 + j*(-211) -404 + j*(-189) -191 + j*(403) -511 + j*(-279) --544 + j*(202) -136 + j*(-401) -363 + j*(-269) --499 + j*(-64) -385 + j*(549) -243 + j*(250) --209 + j*(393) --231 + j*(-198) -272 + j*(-286) -133 + j*(-260) --366 + j*(-317) --76 + j*(25) --270 + j*(255) --267 + j*(118) --217 + j*(-233) -313 + j*(370) -282 + j*(-179) --513 + j*(120) --118 + j*(-400) -286 + j*(-403) --231 + j*(133) --175 + j*(-118) --161 + j*(-173) --118 + j*(411) --51 + j*(-93) --542 + j*(16) -233 + j*(-422) --13 + j*(-86) -345 + j*(-467) --296 + j*(-259) --23 + j*(-313) -74 + j*(476) -182 + j*(-244) --266 + j*(-231) --251 + j*(-226) --395 + j*(-360) --156 + j*(550) -217 + j*(163) --486 + j*(433) --281 + j*(248) --65 + j*(67) -232 + j*(-296) --383 + j*(-46) -403 + j*(99) -210 + j*(-325) --217 + j*(-564) --328 + j*(169) --196 + j*(132) --624 + j*(225) --480 + j*(200) --418 + j*(307) -367 + j*(-327) --365 + j*(-371) -422 + j*(-177) -296 + j*(-316) --284 + j*(-382) -414 + j*(163) --542 + j*(-593) -332 + j*(40) --100 + j*(368) -355 + j*(-380) -542 + j*(-166) -63 + j*(267) --427 + j*(293) --83 + j*(206) --610 + j*(45) -348 + j*(-95) -469 + j*(-153) -235 + j*(-150) --285 + j*(380) --399 + j*(-140) -247 + j*(-107) --556 + j*(472) --168 + j*(-3) --204 + j*(-325) -590 + j*(303) --222 + j*(228) -200 + j*(233) -524 + j*(-117) --57 + j*(257) --405 + j*(-373) --441 + j*(-124) -16 + j*(374) -306 + j*(-499) --36 + j*(-2) --103 + j*(-356) -378 + j*(214) --361 + j*(-255) --180 + j*(328) --267 + j*(-305) -204 + j*(-63) -45 + j*(-543) --134 + j*(-142) -321 + j*(508) --412 + j*(549) --240 + j*(182) --353 + j*(177) --138 + j*(-158) -165 + j*(-395) -234 + j*(-400) --256 + j*(373) -37 + j*(-249) -69 + j*(-151) --211 + j*(-291) --209 + j*(-90) --366 + j*(-367) -555 + j*(-146) --202 + j*(-583) --280 + j*(-259) -264 + j*(-309) -595 + j*(80) --318 + j*(-107) --306 + j*(96) -128 + j*(-289) -149 + j*(65) -265 + j*(-255) --399 + j*(-277) -325 + j*(-206) --368 + j*(122) -306 + j*(-187) --261 + j*(329) --223 + j*(-4) -443 + j*(477) --476 + j*(403) -112 + j*(-310) --124 + j*(93) --25 + j*(-349) -404 + j*(-98) --134 + j*(328) --289 + j*(-192) -151 + j*(137) -431 + j*(301) --76 + j*(-70) --161 + j*(-161) --590 + j*(-261) -276 + j*(291) -232 + j*(-365) --383 + j*(-45) -409 + j*(-97) --266 + j*(366) -433 + j*(-146) --308 + j*(18) -238 + j*(80) --52 + j*(299) --250 + j*(499) --395 + j*(358) --83 + j*(-467) -173 + j*(284) -43 + j*(-25) -97 + j*(293) --46 + j*(578) -245 + j*(-372) --127 + j*(197) --59 + j*(-461) -301 + j*(358) --95 + j*(205) --132 + j*(260) --337 + j*(286) --215 + j*(-344) --224 + j*(256) -748 + j*(-341) -402 + j*(-316) -264 + j*(-693) -18 + j*(115) -127 + j*(-64) --18 + j*(-102) --95 + j*(-594) -385 + j*(72) -73 + j*(11) --237 + j*(58) --177 + j*(-98) -117 + j*(-21) --536 + j*(173) -231 + j*(89) --290 + j*(-238) -176 + j*(-135) --293 + j*(50) -112 + j*(33) -73 + j*(-214) -89 + j*(-269) -62 + j*(6) --204 + j*(9) -49 + j*(17) -21 + j*(91) --170 + j*(49) --112 + j*(-310) --247 + j*(168) --28 + j*(221) -98 + j*(-145) -234 + j*(33) --22 + j*(-23) --81 + j*(148) -69 + j*(117) --144 + j*(-127) --62 + j*(4) -76 + j*(149) -76 + j*(-45) --6 + j*(61) -75 + j*(95) --105 + j*(-210) --378 + j*(-561) --334 + j*(86) -309 + j*(-91) -309 + j*(-67) -190 + j*(-124) -91 + j*(23) -8 + j*(-58) --235 + j*(-55) -57 + j*(-322) --93 + j*(133) --189 + j*(-179) -278 + j*(-37) -177 + j*(14) --4 + j*(-166) --71 + j*(-71) -310 + j*(-178) -107 + j*(-23) -153 + j*(55) --146 + j*(350) -17 + j*(70) --94 + j*(180) --69 + j*(181) --124 + j*(-424) --75 + j*(117) --124 + j*(-28) --194 + j*(-111) -45 + j*(58) -12 + j*(-58) -197 + j*(-82) -212 + j*(32) -144 + j*(179) --9 + j*(56) --200 + j*(-328) --64 + j*(70) --48 + j*(332) --71 + j*(-75) --189 + j*(-15) -35 + j*(143) --3 + j*(148) --158 + j*(-24) --69 + j*(165) -74 + j*(73) -149 + j*(-45) --30 + j*(-211) --195 + j*(158) --147 + j*(272) -69 + j*(-50) --73 + j*(54) --309 + j*(-164) --44 + j*(-103) --401 + j*(132) --271 + j*(104) --269 + j*(-28) --303 + j*(267) --21 + j*(281) --47 + j*(34) --164 + j*(-165) --110 + j*(241) --37 + j*(62) --40 + j*(-134) -2 + j*(19) -241 + j*(-375) --301 + j*(-67) -204 + j*(-37) -303 + j*(-142) --8 + j*(184) -60 + j*(-178) --158 + j*(238) -223 + j*(-71) -63 + j*(-277) -144 + j*(-3) --375 + j*(-45) --186 + j*(6) --36 + j*(-61) -46 + j*(-59) --22 + j*(191) --127 + j*(84) --202 + j*(-13) -519 + j*(253) --378 + j*(129) -16 + j*(176) -14 + j*(66) --198 + j*(341) --16 + j*(-180) -16 + j*(54) -42 + j*(49) -116 + j*(127) -60 + j*(-39) --100 + j*(-65) -94 + j*(-66) -126 + j*(150) -396 + j*(-101) --228 + j*(-126) -188 + j*(-42) --88 + j*(-210) --1 + j*(-69) -132 + j*(85) --140 + j*(28) --165 + j*(162) --105 + j*(129) --69 + j*(-122) --130 + j*(-45) --35 + j*(-15) --217 + j*(63) -24 + j*(-269) -67 + j*(103) --230 + j*(-104) -74 + j*(-202) --48 + j*(-80) --175 + j*(-81) --118 + j*(-93) --151 + j*(-15) -300 + j*(-88) --107 + j*(-209) -113 + j*(52) -3 + j*(162) --64 + j*(-366) --180 + j*(-201) -291 + j*(65) -56 + j*(-347) --21 + j*(28) -99 + j*(154) -119 + j*(5) --18 + j*(-43) -101 + j*(-66) -279 + j*(-172) -210 + j*(-234) -119 + j*(-100) -4 + j*(-65) --221 + j*(-33) -177 + j*(33) -289 + j*(240) --134 + j*(261) --474 + j*(50) -274 + j*(-269) -79 + j*(-84) --164 + j*(63) --103 + j*(151) -25 + j*(299) -87 + j*(67) --302 + j*(93) -378 + j*(22) -230 + j*(-15) -70 + j*(-76) -74 + j*(-161) --108 + j*(46) -52 + j*(-183) --117 + j*(20) -351 + j*(-247) -169 + j*(115) -143 + j*(-125) -122 + j*(-360) -173 + j*(199) -337 + j*(-138) --255 + j*(-175) -76 + j*(108) -256 + j*(-67) -184 + j*(-215) -103 + j*(303) -244 + j*(-360) --130 + j*(-75) -98 + j*(-192) --126 + j*(244) -249 + j*(-49) -331 + j*(-116) --232 + j*(-227) -205 + j*(50) --46 + j*(156) -274 + j*(153) --392 + j*(-40) --111 + j*(-1) -45 + j*(-269) -138 + j*(22) -238 + j*(172) --24 + j*(-80) -160 + j*(-28) --56 + j*(280) --26 + j*(-56) -73 + j*(42) -360 + j*(29) -142 + j*(-410) --126 + j*(107) --134 + j*(288) -42 + j*(414) --83 + j*(-246) -170 + j*(19) -1 + j*(-26) --31 + j*(-13) -113 + j*(40) -82 + j*(145) -139 + j*(362) --89 + j*(122) --133 + j*(-552) --269 + j*(-70) --29 + j*(-21) --161 + j*(-243) --134 + j*(-10) -16 + j*(117) -13 + j*(-63) --160 + j*(252) --27 + j*(77) --252 + j*(-119) --65 + j*(167) --71 + j*(259) -62 + j*(-130) --223 + j*(117) --58 + j*(-50) -132 + j*(-72) -21 + j*(157) -56 + j*(-150) --171 + j*(-102) --42 + j*(106) --66 + j*(21) --83 + j*(119) -158 + j*(252) --252 + j*(-111) --47 + j*(92) -46 + j*(-76) --199 + j*(39) --5 + j*(-91) --65 + j*(-152) -308 + j*(-76) -36 + j*(276) --144 + j*(-122) -382 + j*(330) -212 + j*(-305) --23 + j*(-304) --19 + j*(117) -150 + j*(-267) --317 + j*(-182) --100 + j*(33) --23 + j*(92) --258 + j*(-35) -70 + j*(-20) --83 + j*(-13) -138 + j*(98) -301 + j*(-17) -448 + j*(289) -126 + j*(176) -284 + j*(12) --176 + j*(-56) -320 + j*(144) --188 + j*(-220) --7 + j*(-40) -164 + j*(-198) -23 + j*(148) -260 + j*(184) --187 + j*(-52) --47 + j*(146) --234 + j*(-148) -66 + j*(141) -243 + j*(-199) --21 + j*(-17) -178 + j*(42) -204 + j*(93) -106 + j*(135) -14 + j*(88) -135 + j*(-242) --35 + j*(-99) --186 + j*(-61) --167 + j*(-122) --21 + j*(-138) --41 + j*(-13) --83 + j*(-98) -343 + j*(-217) -180 + j*(-9) --476 + j*(-114) --110 + j*(-219) --272 + j*(211) --47 + j*(-130) --395 + j*(-134) --200 + j*(54) --107 + j*(-376) -47 + j*(298) -84 + j*(-206) --355 + j*(115) -42 + j*(147) -211 + j*(119) -18 + j*(-42) --173 + j*(77) --40 + j*(259) --168 + j*(193) --167 + j*(-274) --182 + j*(-132) -45 + j*(124) -351 + j*(-177) -170 + j*(-41) -44 + j*(90) -183 + j*(-95) --361 + j*(60) --24 + j*(-53) -122 + j*(-78) --129 + j*(-28) --160 + j*(92) -35 + j*(83) --105 + j*(41) --86 + j*(-101) --228 + j*(120) --27 + j*(-172) -36 + j*(221) -58 + j*(217) -91 + j*(-128) --58 + j*(-247) --78 + j*(270) -221 + j*(-192) -267 + j*(66) -115 + j*(48) -200 + j*(33) -155 + j*(-253) -172 + j*(93) -260 + j*(-219) -241 + j*(-64) -21 + j*(309) -37 + j*(-251) -238 + j*(-236) --4 + j*(121) -38 + j*(-204) --116 + j*(-143) -349 + j*(137) -60 + j*(23) -174 + j*(-243) -169 + j*(-221) --192 + j*(-170) -124 + j*(-182) -43 + j*(-52) -209 + j*(223) -146 + j*(172) --155 + j*(64) -28 + j*(129) --118 + j*(232) -79 + j*(-8) --294 + j*(40) --414 + j*(-79) -45 + j*(234) -50 + j*(23) --139 + j*(61) -40 + j*(41) -88 + j*(-35) -94 + j*(11) --35 + j*(-146) -54 + j*(117) --107 + j*(5) --321 + j*(-30) --190 + j*(-89) -227 + j*(90) --72 + j*(-39) --107 + j*(-324) --117 + j*(71) --33 + j*(99) --82 + j*(-171) -75 + j*(-69) -33 + j*(151) --106 + j*(-52) -35 + j*(-5) --141 + j*(441) -48 + j*(62) -5 + j*(36) -2 + j*(136) -24 + j*(303) --137 + j*(-233) --249 + j*(241) -53 + j*(-79) -92 + j*(-265) -98 + j*(210) --89 + j*(166) --18 + j*(-91) --62 + j*(-67) -74 + j*(-53) -91 + j*(-283) -330 + j*(77) --16 + j*(-185) -293 + j*(47) --54 + j*(66) -17 + j*(28) --34 + j*(49) -190 + j*(-28) --161 + j*(287) --99 + j*(187) -5 + j*(34) -21 + j*(116) --105 + j*(335) --28 + j*(-32) --74 + j*(-55) -148 + j*(69) -37 + j*(-168) --233 + j*(42) --66 + j*(-16) -115 + j*(-319) -81 + j*(-20) -120 + j*(180) -114 + j*(346) -61 + j*(-107) -143 + j*(-15) -70 + j*(-122) --119 + j*(-272) --39 + j*(129) --163 + j*(103) -76 + j*(169) --243 + j*(-21) --145 + j*(-156) --211 + j*(-214) -127 + j*(340) -79 + j*(-57) --16 + j*(-45) --24 + j*(87) -161 + j*(52) --282 + j*(212) --62 + j*(91) --44 + j*(-33) -81 + j*(151) -69 + j*(68) -237 + j*(-74) --132 + j*(260) -143 + j*(-132) --11 + j*(-6) --49 + j*(88) --28 + j*(138) --341 + j*(6) -231 + j*(35) -88 + j*(81) --4 + j*(-156) -296 + j*(79) --458 + j*(51) -35 + j*(-387) --32 + j*(-234) -88 + j*(-45) --173 + j*(-64) --33 + j*(-172) --204 + j*(-99) --202 + j*(228) -105 + j*(-313) --60 + j*(-256) --104 + j*(-276) -222 + j*(-34) --1 + j*(-357) --98 + j*(-369) --129 + j*(-107) -344 + j*(312) --262 + j*(249) -108 + j*(-228) -364 + j*(-30) --10 + j*(83) --187 + j*(23) -330 + j*(249) -57 + j*(124) -317 + j*(-185) --100 + j*(34) -225 + j*(82) --36 + j*(-7) --25 + j*(71) --90 + j*(-27) --132 + j*(155) --106 + j*(-190) --29 + j*(403) --35 + j*(209) -66 + j*(-105) -137 + j*(-29) -84 + j*(238) --1 + j*(-75) --158 + j*(-138) --120 + j*(349) --66 + j*(-279) -127 + j*(-31) --247 + j*(42) -186 + j*(-256) --69 + j*(-107) -60 + j*(280) -237 + j*(190) --161 + j*(47) --104 + j*(173) -29 + j*(11) -59 + j*(177) --43 + j*(-9) --207 + j*(248) -115 + j*(-81) --122 + j*(57) -20 + j*(-103) --25 + j*(-41) --13 + j*(66) --169 + j*(23) -16 + j*(-243) --83 + j*(-59) -121 + j*(-153) --38 + j*(-99) -269 + j*(252) -303 + j*(-616) --87 + j*(218) --23 + j*(-52) -286 + j*(147) --146 + j*(28) -185 + j*(88) -181 + j*(88) -58 + j*(300) --59 + j*(-236) --152 + j*(-32) --132 + j*(-127) --42 + j*(62) -200 + j*(-16) -178 + j*(87) --10 + j*(-289) -85 + j*(-192) -373 + j*(92) --641 + j*(26) --253 + j*(-136) --87 + j*(38) -7 + j*(-527) -79 + j*(-31) -10 + j*(76) -235 + j*(-160) -78 + j*(-93) -346 + j*(-32) -45 + j*(-271) --30 + j*(269) -180 + j*(-45) --39 + j*(125) --256 + j*(206) --24 + j*(-163) -98 + j*(317) --194 + j*(-140) --76 + j*(-12) -523 + j*(-112) -392 + j*(28) -58 + j*(-8) --118 + j*(-94) --129 + j*(17) --217 + j*(18) -200 + j*(34) --261 + j*(-148) -43 + j*(284) --160 + j*(16) -332 + j*(67) -36 + j*(-7) -324 + j*(-185) --134 + j*(-88) --43 + j*(-363) -161 + j*(-263) --59 + j*(-300) --127 + j*(164) --178 + j*(123) --146 + j*(44) --39 + j*(-35) --131 + j*(-76) --23 + j*(-384) --112 + j*(-11) -86 + j*(177) -127 + j*(107) --75 + j*(-81) -198 + j*(50) -24 + j*(-1) --17 + j*(78) --223 + j*(-136) -257 + j*(152) --81 + j*(81) --128 + j*(255) --16 + j*(201) -16 + j*(187) --143 + j*(-303) --144 + j*(-173) -95 + j*(-123) --264 + j*(177) -449 + j*(-10) -65 + j*(21) --348 + j*(129) --72 + j*(-158) --283 + j*(43) -59 + j*(-156) -113 + j*(20) --1 + j*(115) -201 + j*(25) --91 + j*(-21) -46 + j*(140) --54 + j*(-143) -71 + j*(-136) --296 + j*(-75) --202 + j*(293) --51 + j*(202) --33 + j*(88) -231 + j*(-65) -165 + j*(23) --1 + j*(165) --47 + j*(51) --4 + j*(-314) --141 + j*(-169) -53 + j*(-211) -89 + j*(204) --105 + j*(-218) -61 + j*(-53) --143 + j*(-284) --11 + j*(-369) --54 + j*(-280) -189 + j*(250) --209 + j*(-136) --65 + j*(-126) -25 + j*(168) --137 + j*(165) -41 + j*(-85) -76 + j*(231) --229 + j*(-282) -45 + j*(122) --92 + j*(66) --80 + j*(-161) -57 + j*(-59) --95 + j*(-53) --37 + j*(-35) --20 + j*(103) --124 + j*(-59) --75 + j*(21) --260 + j*(-112) -132 + j*(-57) -183 + j*(6) -243 + j*(-146) -102 + j*(384) --172 + j*(-175) -21 + j*(-363) -192 + j*(-266) -52 + j*(-297) --293 + j*(155) -58 + j*(-263) -207 + j*(14) -62 + j*(-169) --152 + j*(250) -46 + j*(-74) -95 + j*(-74) --75 + j*(147) -29 + j*(8) --140 + j*(-167) -206 + j*(-33) -249 + j*(168) -47 + j*(38) -72 + j*(-209) -52 + j*(32) -123 + j*(294) -316 + j*(-170) --91 + j*(-158) --132 + j*(-92) -124 + j*(127) -215 + j*(110) -95 + j*(141) --309 + j*(-30) -231 + j*(-153) -165 + j*(-54) -71 + j*(-115) --250 + j*(-105) --8 + j*(-131) -251 + j*(214) --199 + j*(-33) -92 + j*(-49) -86 + j*(187) --441 + j*(-16) -303 + j*(46) -163 + j*(-116) -6 + j*(45) --53 + j*(209) -97 + j*(202) -371 + j*(-264) --113 + j*(-148) --70 + j*(-216) --23 + j*(123) --88 + j*(91) --146 + j*(96) -45 + j*(-79) --67 + j*(-41) -51 + j*(-138) --203 + j*(-65) --193 + j*(214) -91 + j*(187) --246 + j*(-214) --300 + j*(153) -21 + j*(-79) --18 + j*(-130) --165 + j*(256) -88 + j*(182) --160 + j*(105) -120 + j*(-272) -440 + j*(327) -98 + j*(3) --104 + j*(107) -215 + j*(84) -398 + j*(-12) -146 + j*(32) -343 + j*(6) --522 + j*(284) -105 + j*(8) -112 + j*(41) --263 + j*(84) --36 + j*(-168) -45 + j*(90) --111 + j*(-188) -1 + j*(83) --159 + j*(40) --345 + j*(59) --17 + j*(-190) --84 + j*(134) -201 + j*(-206) -46 + j*(-110) -136 + j*(-88) -144 + j*(92) --11 + j*(-25) --102 + j*(233) --190 + j*(285) -50 + j*(123) -112 + j*(102) -72 + j*(387) -14 + j*(-137) -33 + j*(111) --60 + j*(-201) --86 + j*(118) -52 + j*(259) -52 + j*(28) -73 + j*(-199) -284 + j*(215) -296 + j*(-136) --103 + j*(146) -1 + j*(49) -120 + j*(-55) -38 + j*(187) --581 + j*(158) -163 + j*(-325) --129 + j*(-29) -257 + j*(113) -135 + j*(250) --246 + j*(-14) --285 + j*(78) --181 + j*(-91) -311 + j*(0) -75 + j*(68) -18 + j*(-100) -144 + j*(43) -324 + j*(95) --107 + j*(69) --133 + j*(-156) --203 + j*(-366) --245 + j*(-175) -72 + j*(39) --6 + j*(-11) --67 + j*(179) --26 + j*(-18) --271 + j*(375) --201 + j*(-147) --57 + j*(-52) -139 + j*(-216) --93 + j*(54) -100 + j*(373) --148 + j*(33) --171 + j*(-137) --43 + j*(98) --4 + j*(-42) --115 + j*(213) -22 + j*(-251) --165 + j*(16) --177 + j*(-170) --275 + j*(184) --153 + j*(-170) --73 + j*(-168) -11 + j*(130) -48 + j*(121) -173 + j*(125) -1 + j*(37) -66 + j*(321) -365 + j*(-200) -240 + j*(107) -231 + j*(-123) --115 + j*(41) --211 + j*(16) --192 + j*(-125) --108 + j*(50) --66 + j*(-6) --8 + j*(-118) -81 + j*(68) -372 + j*(-31) --280 + j*(66) -105 + j*(16) --97 + j*(-85) --175 + j*(-276) --52 + j*(204) --220 + j*(64) --22 + j*(-260) --138 + j*(88) --86 + j*(-236) -0 + j*(13) -40 + j*(-56) --161 + j*(-40) --106 + j*(-194) --265 + j*(-81) -86 + j*(83) --48 + j*(7) -127 + j*(-83) -218 + j*(-228) -155 + j*(88) --195 + j*(288) --69 + j*(-33) --122 + j*(36) --195 + j*(-75) --36 + j*(127) --54 + j*(119) -95 + j*(-52) -18 + j*(-72) --44 + j*(-35) -39 + j*(105) -109 + j*(-2) --190 + j*(79) -171 + j*(301) -67 + j*(-164) -93 + j*(-250) -383 + j*(30) --233 + j*(148) -64 + j*(25) --22 + j*(-25) -73 + j*(160) -457 + j*(196) --23 + j*(6) -154 + j*(35) --78 + j*(-95) -18 + j*(-118) --17 + j*(100) -125 + j*(-159) --107 + j*(47) -18 + j*(342) --83 + j*(-453) -411 + j*(157) -83 + j*(-192) -143 + j*(-182) --266 + j*(-77) -124 + j*(-392) -94 + j*(-190) --200 + j*(261) --146 + j*(-107) -80 + j*(-24) --113 + j*(57) --4 + j*(87) -78 + j*(32) --257 + j*(-225) -252 + j*(98) -121 + j*(222) -20 + j*(15) --233 + j*(-42) --76 + j*(-408) --141 + j*(40) -146 + j*(-282) -52 + j*(-11) -88 + j*(-210) -93 + j*(157) -112 + j*(270) -45 + j*(34) -3 + j*(-139) -20 + j*(197) -86 + j*(-23) --154 + j*(-133) -98 + j*(-40) --356 + j*(-88) --159 + j*(-144) -235 + j*(289) -7 + j*(-182) --52 + j*(-290) -589 + j*(-199) --26 + j*(-64) -14 + j*(-146) --436 + j*(45) --8 + j*(339) --64 + j*(-50) --325 + j*(53) -83 + j*(223) --16 + j*(-254) -192 + j*(-69) -251 + j*(-84) -228 + j*(8) -114 + j*(163) --55 + j*(84) -10 + j*(-61) -193 + j*(84) --214 + j*(-66) --49 + j*(69) --231 + j*(-11) --22 + j*(-81) --199 + j*(90) -264 + j*(138) --331 + j*(71) -132 + j*(122) -147 + j*(7) --77 + j*(-69) -86 + j*(-34) --98 + j*(143) --408 + j*(153) -243 + j*(32) --192 + j*(45) -210 + j*(-25) -2 + j*(16) --516 + j*(-149) -80 + j*(-56) --145 + j*(54) -108 + j*(8) --151 + j*(59) --255 + j*(200) -28 + j*(30) --170 + j*(-214) --14 + j*(14) -221 + j*(3) --190 + j*(-98) --173 + j*(-229) --131 + j*(-164) -313 + j*(-194) -97 + j*(112) -222 + j*(-268) -13 + j*(-59) -117 + j*(-142) -172 + j*(-177) -67 + j*(221) --87 + j*(-32) --144 + j*(93) --135 + j*(-286) -385 + j*(-101) --86 + j*(202) --149 + j*(127) --56 + j*(195) --2 + j*(-35) --5 + j*(-182) -195 + j*(170) -202 + j*(-215) --213 + j*(-109) -101 + j*(-176) -255 + j*(-240) --86 + j*(214) --165 + j*(-35) -242 + j*(-112) --18 + j*(-156) -81 + j*(-96) --4 + j*(120) --97 + j*(8) -217 + j*(195) -256 + j*(-281) -71 + j*(-104) --125 + j*(153) --89 + j*(86) --69 + j*(210) --45 + j*(4) -445 + j*(-89) --50 + j*(-165) --212 + j*(58) -405 + j*(202) -153 + j*(383) --74 + j*(199) -317 + j*(-228) --6 + j*(-18) -24 + j*(-126) -234 + j*(141) --113 + j*(-23) -128 + j*(80) -202 + j*(194) -52 + j*(110) --8 + j*(-151) --58 + j*(132) --171 + j*(115) -54 + j*(49) --151 + j*(-103) -132 + j*(-243) -276 + j*(-27) --361 + j*(-115) --150 + j*(84) --148 + j*(-176) --145 + j*(82) -219 + j*(-160) -184 + j*(-7) -33 + j*(-124) --95 + j*(114) -190 + j*(-218) -141 + j*(-73) --187 + j*(190) --1 + j*(9) -149 + j*(6) -254 + j*(-40) --35 + j*(-286) -151 + j*(303) --139 + j*(-175) --104 + j*(49) --400 + j*(-63) -92 + j*(-197) --318 + j*(10) -25 + j*(-160) --183 + j*(-194) -74 + j*(45) -33 + j*(-66) -124 + j*(-181) --93 + j*(74) -206 + j*(-126) -257 + j*(-97) -18 + j*(9) --128 + j*(64) -119 + j*(125) --140 + j*(11) --257 + j*(7) --356 + j*(-113) --295 + j*(287) --144 + j*(104) -174 + j*(59) --13 + j*(-155) --43 + j*(92) --238 + j*(-49) --195 + j*(238) -112 + j*(-262) --103 + j*(37) -45 + j*(-238) --217 + j*(-295) --153 + j*(156) -281 + j*(88) --107 + j*(-43) -293 + j*(47) --215 + j*(80) --48 + j*(-238) --395 + j*(122) --348 + j*(-60) -11 + j*(40) -216 + j*(56) --78 + j*(163) -8 + j*(-216) -105 + j*(91) -106 + j*(261) --95 + j*(-192) -112 + j*(67) -312 + j*(-171) -168 + j*(-223) --7 + j*(171) --27 + j*(-176) -166 + j*(206) -40 + j*(89) --80 + j*(-222) --120 + j*(-236) --173 + j*(-10) --48 + j*(-100) --228 + j*(-205) -303 + j*(134) -222 + j*(18) --118 + j*(203) --35 + j*(40) -29 + j*(-70) -226 + j*(-18) -164 + j*(59) -173 + j*(-224) -45 + j*(-255) -149 + j*(-78) --10 + j*(-176) --168 + j*(216) -60 + j*(46) -45 + j*(-16) --254 + j*(-35) -116 + j*(28) -87 + j*(170) -91 + j*(-139) -204 + j*(-61) --131 + j*(-184) -158 + j*(184) --118 + j*(-86) -475 + j*(158) -255 + j*(-69) -54 + j*(-293) --11 + j*(91) --74 + j*(-40) --122 + j*(245) --371 + j*(-127) --13 + j*(-100) --156 + j*(1) -71 + j*(-356) --117 + j*(1) --56 + j*(319) --126 + j*(-319) --159 + j*(-66) --115 + j*(188) --153 + j*(257) -187 + j*(-379) -64 + j*(-60) --56 + j*(6) --279 + j*(-78) -437 + j*(-305) -164 + j*(161) -371 + j*(-175) -76 + j*(143) -240 + j*(-185) -14 + j*(187) -381 + j*(134) -65 + j*(-382) -274 + j*(-39) -91 + j*(78) --284 + j*(24) -115 + j*(82) --64 + j*(194) -33 + j*(182) --130 + j*(-107) --77 + j*(-45) --229 + j*(-103) -199 + j*(594) -117 + j*(59) -143 + j*(-350) -123 + j*(31) --86 + j*(-33) --301 + j*(258) -18 + j*(322) -166 + j*(-163) -157 + j*(-4) -201 + j*(228) --115 + j*(-309) --33 + j*(-49) --257 + j*(1) -75 + j*(-115) -45 + j*(367) --37 + j*(-36) --77 + j*(-276) -163 + j*(138) --42 + j*(103) -13 + j*(-232) -56 + j*(110) --30 + j*(-88) --47 + j*(-7) -42 + j*(235) -151 + j*(-332) -257 + j*(-101) -152 + j*(216) --316 + j*(212) --92 + j*(115) -127 + j*(-179) --67 + j*(47) --197 + j*(26) -441 + j*(-165) --227 + j*(124) -49 + j*(45) --81 + j*(368) --62 + j*(-108) -251 + j*(-332) --36 + j*(-64) -147 + j*(-291) --129 + j*(-181) -226 + j*(-194) --74 + j*(-160) --250 + j*(-107) --322 + j*(72) --95 + j*(15) --130 + j*(14) --42 + j*(-41) -23 + j*(-275) --61 + j*(-23) --400 + j*(257) -73 + j*(-130) --119 + j*(-42) --28 + j*(-104) -27 + j*(-366) --64 + j*(209) -84 + j*(206) --176 + j*(-442) -103 + j*(-235) --76 + j*(-279) -99 + j*(52) --264 + j*(-8) --288 + j*(71) -14 + j*(24) --402 + j*(25) --299 + j*(156) --146 + j*(135) --21 + j*(187) --255 + j*(-52) --214 + j*(239) -106 + j*(-19) -63 + j*(-71) -25 + j*(-88) -220 + j*(426) --358 + j*(91) --252 + j*(-223) --54 + j*(-177) -122 + j*(-41) -105 + j*(-161) --65 + j*(84) -252 + j*(10) --168 + j*(-198) -183 + j*(-35) -11 + j*(172) --226 + j*(-230) --184 + j*(-214) --151 + j*(-233) --92 + j*(-59) -31 + j*(100) -16 + j*(331) -125 + j*(81) --301 + j*(-35) -69 + j*(-139) --60 + j*(107) --64 + j*(-63) --43 + j*(-99) --130 + j*(-54) -134 + j*(381) --155 + j*(17) --499 + j*(223) --148 + j*(-124) --95 + j*(226) -247 + j*(-55) --181 + j*(-183) --94 + j*(-284) --287 + j*(-103) --136 + j*(59) -59 + j*(67) -259 + j*(-352) --150 + j*(-10) --43 + j*(119) -69 + j*(30) --106 + j*(351) --38 + j*(-85) -366 + j*(249) -71 + j*(197) -215 + j*(-37) --136 + j*(196) --231 + j*(75) -97 + j*(-383) -103 + j*(95) -99 + j*(-164) -172 + j*(-106) -93 + j*(177) -42 + j*(-337) --23 + j*(-7) -199 + j*(262) --141 + j*(70) -60 + j*(-132) --5 + j*(-18) --40 + j*(117) --18 + j*(127) --224 + j*(245) --200 + j*(-121) --22 + j*(74) --23 + j*(-212) -129 + j*(119) -42 + j*(286) -18 + j*(261) --17 + j*(-211) --72 + j*(84) -327 + j*(-28) -2 + j*(-11) -100 + j*(-301) --37 + j*(9) --66 + j*(-165) -16 + j*(-57) --59 + j*(-22) -49 + j*(158) -338 + j*(144) -11 + j*(87) --276 + j*(-42) --20 + j*(226) --117 + j*(0) --199 + j*(-294) --274 + j*(18) --21 + j*(-148) --173 + j*(216) -103 + j*(101) -162 + j*(18) -301 + j*(157) --43 + j*(486) -174 + j*(-354) --61 + j*(-138) --62 + j*(-337) -24 + j*(161) -106 + j*(-105) -69 + j*(-204) -247 + j*(166) --199 + j*(235) -11 + j*(107) -273 + j*(180) -157 + j*(-83) -174 + j*(21) --88 + j*(192) --171 + j*(-54) -393 + j*(294) --23 + j*(-21) --6 + j*(4) --73 + j*(-25) --319 + j*(-282) --407 + j*(-130) -86 + j*(76) -293 + j*(52) -392 + j*(-10) --297 + j*(-74) -89 + j*(-230) --149 + j*(286) --185 + j*(43) --91 + j*(-103) --277 + j*(-305) --189 + j*(-58) --190 + j*(-8) --54 + j*(-74) -99 + j*(26) --83 + j*(-206) -223 + j*(82) --60 + j*(-88) -342 + j*(-260) --350 + j*(-141) -154 + j*(-4) -48 + j*(-197) -153 + j*(211) -223 + j*(118) -52 + j*(-206) -158 + j*(-131) --368 + j*(49) --180 + j*(-28) -19 + j*(-435) -112 + j*(83) --167 + j*(-94) -161 + j*(284) -317 + j*(196) --108 + j*(-390) --236 + j*(105) --287 + j*(-153) --87 + j*(-1) --42 + j*(-37) --77 + j*(-438) --9 + j*(59) -48 + j*(-317) -395 + j*(133) --83 + j*(86) --60 + j*(16) --31 + j*(-90) -144 + j*(-65) --80 + j*(-160) -42 + j*(-12) --260 + j*(247) --56 + j*(185) -16 + j*(70) --87 + j*(-107) -74 + j*(187) --37 + j*(210) -303 + j*(52) --42 + j*(323) --40 + j*(-14) -54 + j*(119) --30 + j*(100) --129 + j*(-9) -223 + j*(11) --103 + j*(34) -225 + j*(316) --11 + j*(-108) --141 + j*(204) -86 + j*(-39) -50 + j*(361) --120 + j*(-119) -233 + j*(-174) --277 + j*(-74) --126 + j*(169) -58 + j*(-33) --177 + j*(-51) --153 + j*(-271) -151 + j*(119) -215 + j*(18) --69 + j*(-188) -305 + j*(130) --144 + j*(7) --210 + j*(50) -190 + j*(148) -78 + j*(-69) -37 + j*(96) -42 + j*(209) -243 + j*(57) -103 + j*(-252) --69 + j*(101) --43 + j*(-157) --168 + j*(-206) -27 + j*(-35) -100 + j*(-18) -6 + j*(33) --52 + j*(5) -13 + j*(-250) -17 + j*(268) -204 + j*(-153) -210 + j*(-54) --117 + j*(85) --30 + j*(22) --255 + j*(19) --3 + j*(-106) --87 + j*(-130) -50 + j*(-207) -340 + j*(143) --350 + j*(-105) -190 + j*(62) -32 + j*(-141) -21 + j*(289) --322 + j*(394) -29 + j*(-30) -132 + j*(-94) -114 + j*(-328) --195 + j*(372) --228 + j*(-20) -54 + j*(66) --39 + j*(-59) -186 + j*(10) -153 + j*(258) -12 + j*(45) -4 + j*(-96) --33 + j*(54) --210 + j*(116) --369 + j*(72) -28 + j*(180) -93 + j*(114) --98 + j*(208) -211 + j*(119) --148 + j*(-176) --391 + j*(-227) --63 + j*(122) -59 + j*(30) -41 + j*(269) --97 + j*(200) --49 + j*(-78) --208 + j*(261) -25 + j*(-16) --253 + j*(8) -146 + j*(68) -71 + j*(28) -221 + j*(-176) --281 + j*(-49) -278 + j*(134) -83 + j*(168) --66 + j*(543) -260 + j*(-264) --245 + j*(-107) --205 + j*(669) --275 + j*(207) --265 + j*(294) -88 + j*(137) --162 + j*(-23) --410 + j*(-24) --228 + j*(-286) -486 + j*(-153) --10 + j*(112) -113 + j*(-173) -317 + j*(-373) --211 + j*(-313) --163 + j*(-56) -362 + j*(-64) -83 + j*(397) --247 + j*(312) -385 + j*(-145) --151 + j*(74) -361 + j*(161) --247 + j*(451) --320 + j*(-274) -314 + j*(337) -155 + j*(233) -114 + j*(-267) -115 + j*(201) -377 + j*(-134) -194 + j*(218) -36 + j*(202) --598 + j*(232) -122 + j*(-301) -411 + j*(256) -260 + j*(-323) -12 + j*(466) --78 + j*(-218) -267 + j*(-318) --243 + j*(-390) -573 + j*(441) --57 + j*(-368) --492 + j*(141) --271 + j*(-62) -310 + j*(246) -226 + j*(-334) --395 + j*(-523) --323 + j*(166) --339 + j*(-184) -283 + j*(90) --737 + j*(-246) -196 + j*(335) -354 + j*(-433) --33 + j*(13) --402 + j*(-357) -322 + j*(209) -69 + j*(109) -453 + j*(-119) -245 + j*(34) -296 + j*(-48) -283 + j*(-426) -228 + j*(-288) -86 + j*(185) -453 + j*(-25) --137 + j*(255) -77 + j*(-154) --166 + j*(-66) --342 + j*(179) --454 + j*(-412) -387 + j*(-252) -292 + j*(122) -334 + j*(0) --254 + j*(129) --116 + j*(-10) --292 + j*(-6) -268 + j*(-445) --209 + j*(-537) -424 + j*(-64) -279 + j*(-367) --361 + j*(-91) --243 + j*(-316) -250 + j*(-355) -238 + j*(-216) --464 + j*(386) --296 + j*(150) --192 + j*(-322) -151 + j*(-255) -341 + j*(361) --467 + j*(269) --282 + j*(-421) -180 + j*(-375) --428 + j*(-371) -211 + j*(272) -65 + j*(-426) --378 + j*(-335) -158 + j*(-18) --214 + j*(195) --12 + j*(-337) --115 + j*(116) -433 + j*(-126) -228 + j*(-88) --329 + j*(54) -425 + j*(-19) --443 + j*(496) -358 + j*(-255) --401 + j*(272) -285 + j*(172) --81 + j*(405) -10 + j*(-358) --370 + j*(102) --477 + j*(30) -8 + j*(519) --323 + j*(447) --527 + j*(-167) --218 + j*(36) --116 + j*(-40) -501 + j*(-393) -180 + j*(-192) --93 + j*(-530) --57 + j*(-521) -21 + j*(-306) -252 + j*(228) --330 + j*(-42) -35 + j*(-476) --482 + j*(-399) -221 + j*(348) --257 + j*(-202) --110 + j*(-249) -313 + j*(-1) --303 + j*(51) --374 + j*(683) -339 + j*(279) -428 + j*(363) -18 + j*(-341) -355 + j*(508) --128 + j*(265) --309 + j*(-98) --28 + j*(-35) --439 + j*(231) -499 + j*(458) --546 + j*(-80) --31 + j*(395) --47 + j*(-1) -135 + j*(-437) -299 + j*(126) -161 + j*(424) -275 + j*(-41) --172 + j*(77) --433 + j*(57) -477 + j*(-182) -334 + j*(349) -233 + j*(-412) -414 + j*(93) -93 + j*(103) --146 + j*(-267) --232 + j*(-346) -324 + j*(204) --500 + j*(-10) -276 + j*(-453) -23 + j*(-245) -343 + j*(-359) -419 + j*(-468) -517 + j*(83) -332 + j*(583) -355 + j*(-421) --238 + j*(-115) -729 + j*(-23) -218 + j*(148) -305 + j*(-159) --265 + j*(102) --346 + j*(109) -343 + j*(140) -504 + j*(-364) --424 + j*(-228) --202 + j*(64) --35 + j*(265) --456 + j*(599) --388 + j*(-223) -83 + j*(-33) -375 + j*(-334) --115 + j*(53) -383 + j*(387) -110 + j*(-587) -518 + j*(49) -318 + j*(418) --219 + j*(-455) --37 + j*(-326) --233 + j*(182) --334 + j*(406) -559 + j*(327) --398 + j*(265) --517 + j*(-204) -436 + j*(204) -260 + j*(644) -407 + j*(-289) -355 + j*(-119) -377 + j*(-563) -171 + j*(-69) -313 + j*(-574) -228 + j*(-445) --118 + j*(-154) --161 + j*(424) -124 + j*(-366) -335 + j*(-135) --99 + j*(-424) -437 + j*(506) -490 + j*(747) -272 + j*(79) --28 + j*(-279) -214 + j*(333) --190 + j*(251) -220 + j*(-320) -18 + j*(298) -292 + j*(136) --164 + j*(-386) --437 + j*(373) --122 + j*(-311) -59 + j*(-512) -115 + j*(-47) -371 + j*(105) -432 + j*(-331) --418 + j*(247) --438 + j*(356) -231 + j*(-129) --334 + j*(178) --309 + j*(-184) -269 + j*(460) --460 + j*(118) -537 + j*(36) -550 + j*(224) -275 + j*(-334) --344 + j*(245) --120 + j*(-237) -122 + j*(-154) -68 + j*(-146) -68 + j*(-363) --211 + j*(-162) --258 + j*(-269) -560 + j*(-274) -145 + j*(-81) -562 + j*(231) --363 + j*(-486) -429 + j*(-189) -317 + j*(286) -298 + j*(-331) -110 + j*(-121) -4 + j*(-651) -4 + j*(648) -318 + j*(506) -478 + j*(79) -103 + j*(40) --136 + j*(-419) -412 + j*(-26) --493 + j*(290) --364 + j*(513) -158 + j*(35) --472 + j*(-109) --293 + j*(-365) -372 + j*(437) --171 + j*(-282) --439 + j*(202) --136 + j*(202) --196 + j*(427) --387 + j*(283) --329 + j*(118) --320 + j*(-251) --141 + j*(382) -290 + j*(-96) -262 + j*(-165) --173 + j*(-39) -126 + j*(-477) --247 + j*(299) --247 + j*(382) --315 + j*(356) -141 + j*(-220) -291 + j*(-223) -281 + j*(448) -287 + j*(90) -457 + j*(-190) --184 + j*(438) -302 + j*(-472) --176 + j*(286) --207 + j*(-400) -439 + j*(-117) -74 + j*(125) -292 + j*(-349) -299 + j*(-208) --30 + j*(-268) --59 + j*(-288) --226 + j*(-315) --499 + j*(-209) --340 + j*(423) --389 + j*(-105) --170 + j*(-335) --76 + j*(225) --312 + j*(88) -379 + j*(303) -284 + j*(-255) --291 + j*(296) -601 + j*(220) -207 + j*(105) -148 + j*(313) -281 + j*(420) --402 + j*(382) --141 + j*(148) --74 + j*(318) --618 + j*(-348) --385 + j*(-310) -448 + j*(233) -471 + j*(-279) -9 + j*(125) --191 + j*(-74) -559 + j*(529) --421 + j*(-25) -615 + j*(-308) --161 + j*(370) -493 + j*(-135) --39 + j*(-309) --270 + j*(-256) -527 + j*(8) --204 + j*(474) -88 + j*(514) --276 + j*(-429) -238 + j*(277) --216 + j*(165) --202 + j*(-349) --73 + j*(-279) -267 + j*(279) --186 + j*(-200) --404 + j*(639) -233 + j*(-351) -304 + j*(-202) --91 + j*(-161) -383 + j*(-247) --437 + j*(-287) --275 + j*(-8) -453 + j*(-290) -305 + j*(-100) -323 + j*(-377) -22 + j*(112) --371 + j*(-85) --23 + j*(-8) -276 + j*(173) -226 + j*(120) --491 + j*(337) --245 + j*(497) -368 + j*(-130) -77 + j*(190) -378 + j*(34) --298 + j*(187) -146 + j*(322) --494 + j*(-216) --312 + j*(80) -361 + j*(195) -213 + j*(-537) --49 + j*(-452) --282 + j*(-228) --171 + j*(382) -74 + j*(-387) --382 + j*(378) -513 + j*(-339) -67 + j*(-65) -301 + j*(-3) -438 + j*(-215) --516 + j*(100) -55 + j*(-149) --47 + j*(-359) -92 + j*(-285) --182 + j*(193) -152 + j*(-314) --270 + j*(255) --334 + j*(-128) -299 + j*(-450) --197 + j*(311) --231 + j*(-173) -458 + j*(-262) --206 + j*(477) --338 + j*(202) --37 + j*(454) --477 + j*(-1) --157 + j*(-477) --339 + j*(-322) --278 + j*(607) -257 + j*(-292) --199 + j*(77) -132 + j*(182) --314 + j*(-312) --439 + j*(366) --319 + j*(-279) -358 + j*(74) --198 + j*(-170) -557 + j*(-256) --207 + j*(-424) --472 + j*(-307) -158 + j*(228) --80 + j*(-64) -395 + j*(383) --168 + j*(-6) --40 + j*(-215) -78 + j*(-342) --28 + j*(97) -357 + j*(73) --584 + j*(-170) --510 + j*(296) --155 + j*(42) -187 + j*(13) -510 + j*(334) -113 + j*(-436) --448 + j*(265) --327 + j*(184) -128 + j*(141) -211 + j*(-30) -139 + j*(197) --36 + j*(65) -546 + j*(220) -473 + j*(-143) --139 + j*(175) --473 + j*(243) -247 + j*(-214) -18 + j*(262) -28 + j*(-354) -140 + j*(-25) --325 + j*(-457) --284 + j*(-313) -229 + j*(-353) --337 + j*(-385) -448 + j*(501) --292 + j*(-126) -484 + j*(-617) --291 + j*(-453) --297 + j*(-247) -347 + j*(-323) -204 + j*(-272) --252 + j*(-155) --148 + j*(-477) -166 + j*(378) -142 + j*(0) -174 + j*(438) -653 + j*(-51) -259 + j*(458) --282 + j*(237) -13 + j*(350) --537 + j*(365) -215 + j*(315) -467 + j*(129) -244 + j*(-213) -285 + j*(1) -182 + j*(-56) -135 + j*(-305) -208 + j*(-312) -612 + j*(-123) -303 + j*(473) -102 + j*(-471) --190 + j*(-270) -3 + j*(-470) -192 + j*(483) -94 + j*(-435) --69 + j*(333) -527 + j*(9) --203 + j*(201) -159 + j*(1) --428 + j*(333) -54 + j*(-194) -391 + j*(303) --171 + j*(-295) -315 + j*(-127) -260 + j*(197) --146 + j*(-67) -297 + j*(446) --474 + j*(285) --95 + j*(165) -286 + j*(-295) --482 + j*(-386) -37 + j*(-359) --295 + j*(-119) -187 + j*(-374) -359 + j*(-55) --294 + j*(-349) -301 + j*(301) -148 + j*(-211) --259 + j*(-183) --325 + j*(28) --144 + j*(39) --403 + j*(-242) --465 + j*(49) -176 + j*(-325) -262 + j*(-41) -547 + j*(260) --316 + j*(65) -425 + j*(-1) -310 + j*(-226) --163 + j*(-569) --361 + j*(268) -385 + j*(-217) --474 + j*(-19) --143 + j*(238) --280 + j*(-138) -170 + j*(233) -124 + j*(-78) -593 + j*(348) --291 + j*(-136) -98 + j*(542) --211 + j*(-704) -431 + j*(-303) -79 + j*(-228) -134 + j*(-62) --247 + j*(-397) -567 + j*(52) -521 + j*(-226) -368 + j*(-127) --654 + j*(28) --457 + j*(595) --162 + j*(-465) --161 + j*(-552) -202 + j*(-199) --409 + j*(-440) -623 + j*(137) -305 + j*(6) --115 + j*(-160) -206 + j*(-120) -182 + j*(285) --478 + j*(-85) --197 + j*(-403) -119 + j*(-354) --308 + j*(349) -482 + j*(-368) --296 + j*(96) --27 + j*(141) -665 + j*(389) -458 + j*(179) --8 + j*(-435) --648 + j*(-80) --403 + j*(192) --212 + j*(161) -319 + j*(-486) -222 + j*(-178) -308 + j*(338) --88 + j*(-101) -406 + j*(-424) --95 + j*(-590) --412 + j*(-542) --64 + j*(-274) --245 + j*(320) -144 + j*(192) -144 + j*(300) -225 + j*(-187) --200 + j*(352) --576 + j*(-369) -86 + j*(-57) -243 + j*(-177) --106 + j*(-433) -275 + j*(361) -85 + j*(164) --300 + j*(338) --659 + j*(-456) --293 + j*(-298) --453 + j*(209) --493 + j*(165) --635 + j*(-501) --353 + j*(357) --294 + j*(184) -47 + j*(-356) -251 + j*(37) -490 + j*(250) --204 + j*(-330) -344 + j*(291) -110 + j*(165) -97 + j*(18) -540 + j*(-192) --569 + j*(-88) --135 + j*(95) --326 + j*(-617) -115 + j*(-14) -263 + j*(-353) -436 + j*(-301) -83 + j*(265) --94 + j*(269) --194 + j*(-245) --6 + j*(-158) --156 + j*(-540) -476 + j*(313) -308 + j*(-288) --74 + j*(-361) --286 + j*(-144) -332 + j*(-60) -327 + j*(147) --452 + j*(477) -95 + j*(116) -477 + j*(413) -343 + j*(427) -548 + j*(351) --358 + j*(108) --147 + j*(-146) --383 + j*(-209) --431 + j*(-528) -555 + j*(473) -233 + j*(-53) --44 + j*(-122) -339 + j*(626) --10 + j*(-454) --10 + j*(484) --222 + j*(225) --47 + j*(90) -170 + j*(162) -61 + j*(-95) -25 + j*(-11) -74 + j*(269) --2 + j*(243) -3 + j*(30) --267 + j*(-80) -59 + j*(374) --35 + j*(-372) -165 + j*(221) --102 + j*(-175) --34 + j*(-115) --75 + j*(-95) -126 + j*(88) --245 + j*(194) --351 + j*(72) -33 + j*(47) --87 + j*(-266) --95 + j*(165) --56 + j*(42) -179 + j*(123) --30 + j*(170) -5 + j*(-428) -279 + j*(346) --349 + j*(-42) --9 + j*(-86) --62 + j*(293) -344 + j*(-372) -148 + j*(-54) --160 + j*(-57) --57 + j*(109) --88 + j*(128) --73 + j*(156) --130 + j*(60) --206 + j*(472) --129 + j*(4) -231 + j*(-168) --84 + j*(-132) --189 + j*(310) --64 + j*(-107) -274 + j*(-236) --53 + j*(-1) -8 + j*(-197) -327 + j*(-13) -85 + j*(321) -41 + j*(158) -134 + j*(267) -53 + j*(129) -42 + j*(-11) -144 + j*(-164) -216 + j*(29) --70 + j*(-49) --153 + j*(-78) -303 + j*(91) -248 + j*(-240) -60 + j*(191) -51 + j*(51) -38 + j*(30) --110 + j*(72) -395 + j*(-380) --98 + j*(-201) --21 + j*(-40) -26 + j*(122) -6 + j*(268) --85 + j*(78) -105 + j*(49) -152 + j*(-69) -277 + j*(134) -59 + j*(-185) --112 + j*(-143) --12 + j*(275) --103 + j*(-44) --190 + j*(-227) --245 + j*(105) --21 + j*(-148) --67 + j*(45) -154 + j*(128) --110 + j*(-153) --33 + j*(-143) --88 + j*(-81) -163 + j*(-1) -42 + j*(-227) -93 + j*(1) -202 + j*(-52) -305 + j*(58) --170 + j*(-458) --181 + j*(418) -291 + j*(402) --198 + j*(166) -196 + j*(-259) --263 + j*(186) -77 + j*(137) -59 + j*(-204) -379 + j*(-7) --19 + j*(64) -235 + j*(35) -81 + j*(-90) -24 + j*(79) -54 + j*(-92) --119 + j*(-243) -99 + j*(187) --18 + j*(109) -139 + j*(-76) --267 + j*(-52) --111 + j*(92) -6 + j*(-2) -57 + j*(158) -158 + j*(-405) --224 + j*(242) -271 + j*(-42) -131 + j*(-201) -151 + j*(192) --50 + j*(42) -333 + j*(-21) --34 + j*(-134) --121 + j*(110) --480 + j*(-63) -40 + j*(-447) --150 + j*(147) -90 + j*(-212) --186 + j*(-5) -174 + j*(-49) --319 + j*(91) -145 + j*(-51) --251 + j*(-44) -57 + j*(13) --9 + j*(-190) --72 + j*(107) -54 + j*(114) -156 + j*(20) --134 + j*(98) --89 + j*(-16) --120 + j*(-82) --135 + j*(-173) -307 + j*(-235) --24 + j*(-242) -132 + j*(-212) --139 + j*(-104) -349 + j*(-211) -23 + j*(146) -65 + j*(25) --104 + j*(140) --110 + j*(115) --97 + j*(-174) -162 + j*(35) -86 + j*(-174) -222 + j*(48) -136 + j*(279) --100 + j*(-28) --5 + j*(-159) -49 + j*(-167) --3 + j*(230) --57 + j*(12) -136 + j*(-295) -62 + j*(-274) --178 + j*(-213) --34 + j*(284) -102 + j*(174) --112 + j*(83) -99 + j*(161) --141 + j*(-249) -16 + j*(21) -135 + j*(-135) -62 + j*(162) -23 + j*(-67) --128 + j*(-1) --24 + j*(-153) -8 + j*(128) -134 + j*(-47) --240 + j*(185) -18 + j*(310) --136 + j*(108) --266 + j*(-65) -174 + j*(33) --188 + j*(18) --146 + j*(180) -128 + j*(-28) -339 + j*(157) --163 + j*(215) -148 + j*(26) --57 + j*(-83) --116 + j*(82) --91 + j*(110) --258 + j*(1) --128 + j*(-60) -26 + j*(-158) --87 + j*(-183) -1 + j*(12) --73 + j*(313) -265 + j*(-34) --39 + j*(-241) --30 + j*(66) -81 + j*(-78) -97 + j*(-133) --57 + j*(-127) -94 + j*(-61) -228 + j*(-84) --77 + j*(276) -76 + j*(86) --38 + j*(-375) --130 + j*(136) --11 + j*(-57) --182 + j*(25) -40 + j*(-249) --206 + j*(100) -0 + j*(119) --240 + j*(-139) --165 + j*(55) -170 + j*(-28) -361 + j*(-87) -91 + j*(132) -10 + j*(139) --154 + j*(-103) -37 + j*(39) --142 + j*(-283) -181 + j*(207) --1 + j*(-238) --273 + j*(93) -27 + j*(-272) --78 + j*(-228) -322 + j*(-95) --100 + j*(-489) --257 + j*(-308) --112 + j*(302) -145 + j*(243) --69 + j*(88) --78 + j*(-173) -96 + j*(107) --100 + j*(178) --348 + j*(45) --27 + j*(30) -267 + j*(-211) -52 + j*(-66) -236 + j*(-195) -339 + j*(-69) -351 + j*(125) --79 + j*(-368) -71 + j*(4) --151 + j*(159) --47 + j*(-404) --266 + j*(209) -175 + j*(46) --301 + j*(-93) -281 + j*(-106) --25 + j*(-88) --96 + j*(-258) -160 + j*(-1) -128 + j*(28) -11 + j*(43) -137 + j*(412) --276 + j*(141) -64 + j*(-101) --82 + j*(-85) --194 + j*(100) --305 + j*(-136) -45 + j*(175) --28 + j*(-45) -190 + j*(169) -265 + j*(74) -264 + j*(-54) --26 + j*(112) --264 + j*(177) --255 + j*(320) -127 + j*(70) -184 + j*(-347) -132 + j*(244) -298 + j*(-8) --182 + j*(-144) --226 + j*(175) --40 + j*(323) -200 + j*(-257) --293 + j*(282) -11 + j*(-280) --1 + j*(-445) -18 + j*(-180) -134 + j*(10) --3 + j*(-98) -262 + j*(-4) -45 + j*(153) -376 + j*(84) --324 + j*(185) --197 + j*(-124) --152 + j*(-61) --40 + j*(-2) --173 + j*(-68) -98 + j*(108) -261 + j*(-73) -119 + j*(76) -28 + j*(-102) --305 + j*(-276) -243 + j*(180) --221 + j*(128) -64 + j*(-102) --108 + j*(267) --8 + j*(-108) --116 + j*(139) --91 + j*(-62) -24 + j*(25) --83 + j*(98) -45 + j*(-124) -173 + j*(47) --124 + j*(-233) --47 + j*(-125) --88 + j*(-132) --21 + j*(277) --112 + j*(-133) -88 + j*(97) --320 + j*(354) -338 + j*(259) --6 + j*(-208) --8 + j*(-50) -310 + j*(-15) --33 + j*(-134) -93 + j*(-54) -70 + j*(-214) -10 + j*(-65) -123 + j*(78) -317 + j*(147) --209 + j*(-153) -513 + j*(-206) --306 + j*(-128) -27 + j*(-395) -112 + j*(90) --17 + j*(35) --57 + j*(-4) --122 + j*(-385) -30 + j*(-61) --167 + j*(238) -269 + j*(265) -203 + j*(41) -253 + j*(70) -52 + j*(-152) --53 + j*(-49) -96 + j*(49) --202 + j*(-424) -34 + j*(-286) --505 + j*(-199) --190 + j*(166) -308 + j*(-265) --186 + j*(451) --331 + j*(-117) -115 + j*(64) --171 + j*(111) --106 + j*(266) -143 + j*(-148) --13 + j*(16) --168 + j*(375) -211 + j*(150) --470 + j*(104) --274 + j*(-323) -198 + j*(76) -115 + j*(349) --244 + j*(129) --5 + j*(-64) -309 + j*(-34) -18 + j*(107) -482 + j*(76) -136 + j*(245) --91 + j*(-34) --130 + j*(153) -83 + j*(-168) -0 + j*(-32) -23 + j*(-372) --44 + j*(-225) --228 + j*(-75) -28 + j*(244) --141 + j*(82) --149 + j*(-58) --271 + j*(-217) --331 + j*(270) --100 + j*(-6) -185 + j*(-83) -325 + j*(-273) -226 + j*(-206) -240 + j*(86) --154 + j*(-227) --48 + j*(-69) --42 + j*(72) -377 + j*(137) -62 + j*(-402) --53 + j*(-8) -29 + j*(63) --30 + j*(204) --255 + j*(390) -233 + j*(180) --53 + j*(-97) --42 + j*(-55) --32 + j*(-76) -66 + j*(410) -33 + j*(243) -163 + j*(-12) --195 + j*(-38) -254 + j*(98) --132 + j*(-132) -7 + j*(-87) -136 + j*(240) -59 + j*(42) -225 + j*(-68) --159 + j*(152) --129 + j*(-4) -269 + j*(-86) --37 + j*(79) --436 + j*(-71) --23 + j*(211) -163 + j*(176) --89 + j*(-98) --129 + j*(-387) -118 + j*(8) -38 + j*(-47) -337 + j*(-88) --4 + j*(-1) -231 + j*(-82) -54 + j*(366) --73 + j*(138) --8 + j*(-69) --163 + j*(135) --159 + j*(-257) --214 + j*(-268) --60 + j*(-36) -69 + j*(182) -172 + j*(115) --105 + j*(288) -77 + j*(-184) --107 + j*(101) -248 + j*(45) -61 + j*(-101) -292 + j*(-93) -69 + j*(-192) -143 + j*(66) --279 + j*(138) --74 + j*(-21) -371 + j*(-74) -134 + j*(300) --71 + j*(8) -108 + j*(-291) -4 + j*(129) --373 + j*(-51) -59 + j*(-117) -189 + j*(-206) -206 + j*(28) --242 + j*(-433) --98 + j*(-260) --102 + j*(169) --82 + j*(33) --11 + j*(-184) --24 + j*(-47) -77 + j*(-71) --117 + j*(-44) -204 + j*(-164) --10 + j*(-81) -179 + j*(-16) -68 + j*(-293) -22 + j*(37) -202 + j*(104) -30 + j*(45) -192 + j*(180) --136 + j*(-117) -120 + j*(173) --202 + j*(148) --172 + j*(173) --28 + j*(190) -115 + j*(-58) --167 + j*(199) --95 + j*(212) -168 + j*(-260) --250 + j*(-95) --35 + j*(100) --360 + j*(-88) --163 + j*(75) -335 + j*(-58) --14 + j*(151) --169 + j*(104) -334 + j*(105) --157 + j*(102) --45 + j*(316) --64 + j*(-126) --4 + j*(-431) --91 + j*(-217) -13 + j*(-134) -52 + j*(409) -160 + j*(14) -89 + j*(9) --217 + j*(5) --177 + j*(-442) -225 + j*(-34) --110 + j*(-98) -130 + j*(-428) --225 + j*(212) -44 + j*(-217) -40 + j*(-213) --158 + j*(30) -16 + j*(49) -101 + j*(-322) --93 + j*(38) -330 + j*(214) --61 + j*(18) -285 + j*(34) --228 + j*(-156) -146 + j*(83) --427 + j*(-93) --119 + j*(58) --91 + j*(-428) --177 + j*(-75) -62 + j*(-10) --29 + j*(-49) --76 + j*(95) -62 + j*(-320) --144 + j*(88) -197 + j*(-121) -243 + j*(-54) -113 + j*(223) -59 + j*(-157) -136 + j*(-99) -145 + j*(-90) --283 + j*(-42) --247 + j*(-106) -99 + j*(-380) --8 + j*(-124) --28 + j*(-31) -407 + j*(250) --198 + j*(-94) -244 + j*(154) -119 + j*(501) -82 + j*(315) -16 + j*(122) --6 + j*(-247) --162 + j*(300) -103 + j*(-98) -221 + j*(-177) --80 + j*(207) -43 + j*(105) -8 + j*(2) -251 + j*(-303) -143 + j*(-45) -209 + j*(-18) --35 + j*(76) --191 + j*(254) -178 + j*(-18) -66 + j*(-378) -45 + j*(-7) --159 + j*(-144) --282 + j*(-106) --225 + j*(2) --107 + j*(-255) -92 + j*(226) --39 + j*(-218) --102 + j*(139) -184 + j*(77) --78 + j*(134) -56 + j*(-278) --35 + j*(-81) --61 + j*(-204) --65 + j*(-25) --202 + j*(163) -310 + j*(-28) --111 + j*(-95) --2 + j*(141) --173 + j*(-51) --21 + j*(182) --257 + j*(-57) --83 + j*(81) --267 + j*(52) -2 + j*(13) -35 + j*(59) -105 + j*(190) --306 + j*(-253) -19 + j*(88) --3 + j*(-221) -234 + j*(-160) --9 + j*(-108) --325 + j*(356) --71 + j*(268) --308 + j*(364) --308 + j*(183) -193 + j*(-95) -62 + j*(-12) -107 + j*(42) --100 + j*(62) --84 + j*(57) --90 + j*(-427) --73 + j*(-35) --191 + j*(134) --48 + j*(-85) -193 + j*(-242) --80 + j*(61) -225 + j*(-24) --179 + j*(-218) -353 + j*(394) -197 + j*(109) -228 + j*(9) -386 + j*(167) -86 + j*(-8) -55 + j*(-312) --18 + j*(78) --32 + j*(-191) --24 + j*(20) -121 + j*(-126) --80 + j*(16) --161 + j*(367) --64 + j*(109) --22 + j*(37) --145 + j*(65) --197 + j*(-272) -103 + j*(-46) --98 + j*(99) --325 + j*(-251) -43 + j*(-93) --54 + j*(-3) -193 + j*(-82) -91 + j*(57) -80 + j*(-122) -151 + j*(-258) -36 + j*(-443) --69 + j*(-25) --116 + j*(-222) --12 + j*(-306) --298 + j*(-242) -243 + j*(-248) -94 + j*(-47) --65 + j*(103) --246 + j*(128) --27 + j*(52) --165 + j*(235) --88 + j*(41) --21 + j*(-100) --2 + j*(222) --156 + j*(163) -209 + j*(279) -55 + j*(177) --209 + j*(-136) -132 + j*(-42) --221 + j*(-51) -91 + j*(62) --34 + j*(129) --217 + j*(-257) -6 + j*(-36) --353 + j*(-90) --7 + j*(-86) -105 + j*(81) -148 + j*(-40) --20 + j*(-6) -93 + j*(-156) -145 + j*(120) --110 + j*(465) --39 + j*(23) --54 + j*(138) --69 + j*(87) --91 + j*(-74) -361 + j*(26) -513 + j*(-134) --293 + j*(-134) -18 + j*(-93) -424 + j*(177) --22 + j*(40) -173 + j*(74) -2 + j*(-207) --162 + j*(-165) -57 + j*(128) -315 + j*(80) --102 + j*(117) -238 + j*(-75) --107 + j*(134) --204 + j*(-153) --170 + j*(-9) -2 + j*(50) -88 + j*(110) --8 + j*(-115) --92 + j*(-237) --52 + j*(265) --40 + j*(16) --74 + j*(-80) --150 + j*(-26) --33 + j*(-29) -383 + j*(-48) --182 + j*(247) --192 + j*(260) -108 + j*(133) -175 + j*(-317) --12 + j*(-103) --24 + j*(-373) -141 + j*(-220) -170 + j*(-106) --112 + j*(-248) -180 + j*(-78) --252 + j*(-380) --39 + j*(-247) --152 + j*(39) -28 + j*(-119) --47 + j*(-174) -101 + j*(87) -127 + j*(77) -103 + j*(-255) -66 + j*(257) --105 + j*(32) -78 + j*(69) -26 + j*(-54) --31 + j*(73) -346 + j*(346) -8 + j*(26) --37 + j*(-59) -21 + j*(194) --28 + j*(183) -100 + j*(-55) --157 + j*(175) --322 + j*(-137) --33 + j*(132) --477 + j*(-62) -332 + j*(-111) -83 + j*(282) --134 + j*(92) --269 + j*(-296) --4 + j*(5) -69 + j*(-35) --299 + j*(14) -154 + j*(-176) --137 + j*(11) -156 + j*(-180) --66 + j*(-36) --10 + j*(57) --261 + j*(-361) --36 + j*(74) --31 + j*(147) --19 + j*(-169) -149 + j*(256) --332 + j*(29) --293 + j*(-197) -117 + j*(-184) -235 + j*(134) -251 + j*(86) -54 + j*(-310) -13 + j*(-11) --385 + j*(-286) --2 + j*(-37) --115 + j*(-48) -197 + j*(-20) -264 + j*(136) --243 + j*(-59) --187 + j*(30) -92 + j*(28) --91 + j*(-238) --93 + j*(-179) -6 + j*(76) -11 + j*(6) --96 + j*(78) -25 + j*(59) -110 + j*(523) -141 + j*(-14) --94 + j*(-10) -22 + j*(-120) -443 + j*(-14) -95 + j*(-174) --141 + j*(125) --12 + j*(-354) --193 + j*(-144) --156 + j*(-74) -210 + j*(317) -281 + j*(-52) -77 + j*(89) -21 + j*(-80) -332 + j*(-6) -292 + j*(18) -57 + j*(-45) --65 + j*(113) --317 + j*(-109) --378 + j*(-298) -185 + j*(1) --453 + j*(-45) -123 + j*(279) -27 + j*(57) --299 + j*(23) -112 + j*(47) --47 + j*(174) -33 + j*(-227) --288 + j*(9) --153 + j*(5) -250 + j*(52) --119 + j*(-208) -127 + j*(262) --30 + j*(-109) -55 + j*(-247) --112 + j*(-44) --82 + j*(-38) --297 + j*(-16) -59 + j*(60) --198 + j*(-55) -204 + j*(-151) -12 + j*(40) --627 + j*(-236) --112 + j*(-281) --91 + j*(-167) -38 + j*(83) --146 + j*(130) --228 + j*(29) --67 + j*(-216) -100 + j*(30) -137 + j*(190) -173 + j*(337) -252 + j*(-108) -431 + j*(-163) -217 + j*(-54) --156 + j*(-250) -286 + j*(-232) -286 + j*(-181) --103 + j*(-117) --177 + j*(81) --246 + j*(-159) --254 + j*(58) -69 + j*(157) --110 + j*(34) -262 + j*(95) --130 + j*(148) -144 + j*(345) -152 + j*(25) -89 + j*(236) -257 + j*(146) -50 + j*(-297) -109 + j*(207) -105 + j*(-262) -330 + j*(-397) --221 + j*(-162) -60 + j*(-54) -49 + j*(-194) -24 + j*(-104) --45 + j*(-18) --180 + j*(266) --25 + j*(183) -64 + j*(221) -302 + j*(409) --55 + j*(3) -226 + j*(-310) -37 + j*(-49) --116 + j*(66) -115 + j*(-84) --155 + j*(174) --134 + j*(100) --211 + j*(-69) -226 + j*(-11) -397 + j*(43) -170 + j*(81) --107 + j*(-122) -433 + j*(-25) -115 + j*(-77) --235 + j*(-4) --308 + j*(-138) -187 + j*(241) -49 + j*(8) -62 + j*(105) --296 + j*(122) -33 + j*(497) -334 + j*(-1) -194 + j*(41) -204 + j*(-245) --49 + j*(15) --103 + j*(16) --217 + j*(56) -28 + j*(196) -343 + j*(-173) -173 + j*(164) --100 + j*(167) --94 + j*(-25) --79 + j*(-95) -30 + j*(-276) -144 + j*(61) --120 + j*(-195) --213 + j*(-366) -209 + j*(30) -6 + j*(-245) --43 + j*(-83) -28 + j*(61) -4 + j*(-51) --167 + j*(52) --245 + j*(4) --48 + j*(-92) --53 + j*(210) --156 + j*(-160) --82 + j*(-115) --198 + j*(-206) --134 + j*(-6) -203 + j*(-311) --317 + j*(-81) --66 + j*(-54) -67 + j*(-153) --34 + j*(-26) --14 + j*(-69) -91 + j*(163) --6 + j*(-6) --141 + j*(66) --91 + j*(241) --42 + j*(196) --49 + j*(-35) --175 + j*(-137) -16 + j*(267) -49 + j*(-106) -45 + j*(97) --351 + j*(119) --276 + j*(-46) --109 + j*(94) -3 + j*(170) --182 + j*(323) -97 + j*(-124) --203 + j*(307) --233 + j*(231) --134 + j*(78) -282 + j*(8) -124 + j*(319) -119 + j*(-40) --176 + j*(-145) -26 + j*(42) -97 + j*(-273) --319 + j*(-56) --148 + j*(-65) --12 + j*(242) -16 + j*(165) -264 + j*(85) --181 + j*(-34) -1 + j*(-103) -194 + j*(-12) -14 + j*(260) --251 + j*(-40) --280 + j*(81) --42 + j*(-2) --6 + j*(152) -155 + j*(245) --267 + j*(103) --23 + j*(-334) --177 + j*(100) -8 + j*(-99) -104 + j*(-202) -168 + j*(94) -59 + j*(-193) -57 + j*(116) -98 + j*(-116) --96 + j*(-264) --44 + j*(301) -138 + j*(6) --168 + j*(187) --306 + j*(-88) --163 + j*(-206) --222 + j*(52) -319 + j*(32) -45 + j*(-178) --207 + j*(-179) -160 + j*(-24) -84 + j*(460) -91 + j*(-168) -168 + j*(119) -11 + j*(-8) --145 + j*(195) --145 + j*(-81) -39 + j*(247) --66 + j*(203) -208 + j*(-63) -167 + j*(40) --64 + j*(366) -51 + j*(262) -21 + j*(139) --38 + j*(-226) -158 + j*(-107) --109 + j*(566) -100 + j*(-16) -2 + j*(43) -1 + j*(-100) -23 + j*(-98) --48 + j*(-217) --64 + j*(218) -105 + j*(-83) --186 + j*(104) --64 + j*(-268) -1 + j*(131) --219 + j*(-175) --100 + j*(69) -34 + j*(-469) -199 + j*(177) -305 + j*(-176) --184 + j*(-29) --332 + j*(50) -309 + j*(93) --19 + j*(-73) --21 + j*(-3) -56 + j*(81) -171 + j*(-164) -62 + j*(-228) --21 + j*(-373) --88 + j*(-193) -201 + j*(-6) -340 + j*(-322) -207 + j*(7) --89 + j*(-211) --206 + j*(12) --161 + j*(-84) -49 + j*(-272) -132 + j*(-129) --126 + j*(304) -26 + j*(66) --39 + j*(84) --228 + j*(-138) -71 + j*(13) --27 + j*(-319) -157 + j*(104) -98 + j*(291) -187 + j*(-319) -287 + j*(52) --91 + j*(228) --42 + j*(-133) -297 + j*(-35) -28 + j*(-127) -50 + j*(38) -253 + j*(-35) -126 + j*(-69) -153 + j*(-41) --141 + j*(203) --63 + j*(-108) --69 + j*(-134) -274 + j*(273) -255 + j*(-329) -202 + j*(31) --158 + j*(-15) -240 + j*(122) --249 + j*(205) --29 + j*(171) --209 + j*(28) -146 + j*(-77) -124 + j*(-155) --21 + j*(-257) -342 + j*(292) --75 + j*(145) --37 + j*(199) -124 + j*(317) -198 + j*(48) -197 + j*(35) --71 + j*(-55) -235 + j*(-358) --136 + j*(62) --121 + j*(-194) --129 + j*(190) -126 + j*(160) -153 + j*(154) -223 + j*(-95) -78 + j*(-270) -447 + j*(60) --184 + j*(-173) --121 + j*(-134) -141 + j*(-25) -179 + j*(-190) -26 + j*(305) --180 + j*(-13) -123 + j*(-4) -130 + j*(-310) --42 + j*(-91) -71 + j*(286) --192 + j*(33) -130 + j*(206) -147 + j*(2) --38 + j*(-156) -1 + j*(327) --34 + j*(-42) --254 + j*(-168) -189 + j*(227) -143 + j*(32) --211 + j*(-264) --39 + j*(-439) --24 + j*(271) --25 + j*(110) -190 + j*(-4) --102 + j*(-243) --13 + j*(40) --87 + j*(55) -156 + j*(89) -295 + j*(-50) -210 + j*(-263) --303 + j*(70) -86 + j*(-102) --68 + j*(4) -79 + j*(-426) --152 + j*(-158) -93 + j*(36) -52 + j*(-144) -27 + j*(-280) -58 + j*(-16) -82 + j*(2) -57 + j*(-151) --76 + j*(-21) --67 + j*(125) -233 + j*(-44) -72 + j*(-83) -203 + j*(52) --35 + j*(0) -140 + j*(-147) -110 + j*(144) -96 + j*(23) -288 + j*(-122) --67 + j*(85) -300 + j*(-56) --262 + j*(39) -201 + j*(233) --20 + j*(151) --323 + j*(-35) -49 + j*(143) --89 + j*(-158) --66 + j*(-216) --244 + j*(163) -240 + j*(-245) -364 + j*(-71) --205 + j*(280) -66 + j*(-18) --58 + j*(144) -141 + j*(-151) -154 + j*(-25) -202 + j*(-83) -33 + j*(-127) --166 + j*(-157) -451 + j*(-244) --101 + j*(35) -18 + j*(134) -134 + j*(252) --95 + j*(-264) -320 + j*(211) --54 + j*(-52) --145 + j*(122) --10 + j*(247) --359 + j*(164) --93 + j*(-90) --141 + j*(199) --122 + j*(-140) --384 + j*(-230) -34 + j*(2) --190 + j*(276) --49 + j*(185) -197 + j*(-12) --213 + j*(-105) --110 + j*(-62) --1 + j*(163) -54 + j*(12) -74 + j*(-148) --130 + j*(221) --86 + j*(161) -86 + j*(50) --110 + j*(-74) -129 + j*(256) -25 + j*(-84) --35 + j*(-124) -71 + j*(-105) -274 + j*(-267) -298 + j*(-52) --1 + j*(116) -220 + j*(-17) -147 + j*(126) -69 + j*(53) --208 + j*(-60) -197 + j*(115) --140 + j*(13) -122 + j*(-74) -36 + j*(194) --40 + j*(-26) --126 + j*(97) -288 + j*(115) --142 + j*(127) --20 + j*(-21) --117 + j*(79) --73 + j*(308) --430 + j*(132) --129 + j*(161) -83 + j*(56) --63 + j*(-355) --139 + j*(132) -206 + j*(8) -19 + j*(-193) -156 + j*(-25) -20 + j*(-277) -74 + j*(207) --312 + j*(-97) --264 + j*(127) -219 + j*(69) --16 + j*(126) -92 + j*(-206) --227 + j*(164) --172 + j*(-120) -158 + j*(-31) -110 + j*(83) --103 + j*(6) --22 + j*(120) -110 + j*(93) -37 + j*(-170) --148 + j*(136) --23 + j*(12) -59 + j*(61) -117 + j*(119) -163 + j*(283) -263 + j*(95) -334 + j*(65) --169 + j*(80) --129 + j*(543) --163 + j*(179) -46 + j*(193) --177 + j*(232) -206 + j*(13) -203 + j*(67) -42 + j*(31) -119 + j*(-159) --98 + j*(104) -68 + j*(70) -91 + j*(155) -55 + j*(-175) -88 + j*(-54) --148 + j*(-14) -405 + j*(30) -250 + j*(-249) -6 + j*(234) -71 + j*(69) -57 + j*(-92) -194 + j*(44) --104 + j*(175) -136 + j*(-145) -137 + j*(-80) -110 + j*(-363) -240 + j*(-14) --110 + j*(158) --57 + j*(28) --112 + j*(-86) -25 + j*(192) -139 + j*(-252) --250 + j*(-42) -25 + j*(61) --235 + j*(-152) -310 + j*(-206) --341 + j*(-164) --113 + j*(4) --62 + j*(-13) -216 + j*(90) --45 + j*(-161) --129 + j*(-240) -124 + j*(173) -66 + j*(180) -80 + j*(-23) --62 + j*(144) -28 + j*(-5) -115 + j*(184) -75 + j*(-197) --325 + j*(100) -94 + j*(-126) --78 + j*(-344) --107 + j*(302) --243 + j*(-243) -62 + j*(227) --15 + j*(-337) --49 + j*(-74) -88 + j*(134) --91 + j*(81) --34 + j*(103) --112 + j*(233) -253 + j*(151) --45 + j*(-25) -212 + j*(-127) --363 + j*(66) -251 + j*(12) -267 + j*(27) -280 + j*(-414) -136 + j*(131) --32 + j*(-176) -136 + j*(31) --139 + j*(171) -185 + j*(103) -84 + j*(198) -88 + j*(81) -104 + j*(-158) -301 + j*(298) -63 + j*(260) -210 + j*(-169) -112 + j*(-52) --64 + j*(119) --169 + j*(-281) --83 + j*(-310) -274 + j*(-79) -209 + j*(-182) --107 + j*(-240) --86 + j*(4) -202 + j*(16) --387 + j*(75) --81 + j*(85) -17 + j*(260) --348 + j*(-243) --39 + j*(88) -259 + j*(-40) -37 + j*(13) -157 + j*(-121) -40 + j*(-37) -267 + j*(-28) -85 + j*(47) --310 + j*(52) -25 + j*(33) --366 + j*(-264) --58 + j*(120) -36 + j*(-93) -187 + j*(6) -93 + j*(23) -44 + j*(-240) -235 + j*(161) -197 + j*(293) --153 + j*(126) -211 + j*(-71) -213 + j*(-42) -176 + j*(-6) --176 + j*(-40) -33 + j*(64) --81 + j*(-133) -52 + j*(256) -160 + j*(-141) -118 + j*(187) --212 + j*(26) --257 + j*(157) -192 + j*(18) -199 + j*(295) -49 + j*(-94) -2 + j*(208) --83 + j*(-170) --226 + j*(-139) --197 + j*(18) -40 + j*(-130) -144 + j*(-136) -107 + j*(19) --102 + j*(472) --53 + j*(-39) -5 + j*(265) -173 + j*(256) --349 + j*(40) -54 + j*(-140) -66 + j*(132) -64 + j*(73) --141 + j*(95) -327 + j*(-69) --547 + j*(115) -59 + j*(-115) --62 + j*(69) -81 + j*(182) --86 + j*(-208) --100 + j*(-318) -127 + j*(213) -93 + j*(16) -243 + j*(-7) --23 + j*(333) --21 + j*(330) -74 + j*(-50) --40 + j*(-168) -434 + j*(333) -81 + j*(-143) -230 + j*(163) -209 + j*(-187) --33 + j*(270) -132 + j*(-217) --127 + j*(-35) --59 + j*(40) -187 + j*(32) --11 + j*(-143) -156 + j*(245) --18 + j*(-28) --166 + j*(-27) -332 + j*(145) -8 + j*(-192) --11 + j*(-185) --190 + j*(72) --118 + j*(138) -112 + j*(215) --26 + j*(52) -137 + j*(29) --200 + j*(-123) -183 + j*(-187) -93 + j*(35) --336 + j*(-33) -28 + j*(223) --1 + j*(-18) --234 + j*(98) -117 + j*(25) -132 + j*(-174) --430 + j*(-3) -52 + j*(-205) -95 + j*(148) --55 + j*(-199) -20 + j*(-107) --113 + j*(-80) -51 + j*(26) --13 + j*(79) --182 + j*(20) --71 + j*(-19) --16 + j*(-290) --197 + j*(204) -42 + j*(-184) --63 + j*(52) -16 + j*(-112) -164 + j*(-293) --39 + j*(113) -267 + j*(-49) -259 + j*(-80) --65 + j*(55) -151 + j*(112) --21 + j*(113) -64 + j*(-163) -71 + j*(28) -155 + j*(126) -226 + j*(47) -173 + j*(195) -11 + j*(-218) -87 + j*(-64) -126 + j*(-53) -34 + j*(-310) -225 + j*(-183) --148 + j*(-328) -210 + j*(-400) -289 + j*(49) -3 + j*(-170) -231 + j*(54) -136 + j*(21) --83 + j*(273) -108 + j*(251) -429 + j*(277) -6 + j*(294) -103 + j*(207) -16 + j*(-199) -187 + j*(28) -16 + j*(51) -232 + j*(51) --148 + j*(9) -77 + j*(-168) -42 + j*(279) -132 + j*(265) -145 + j*(-90) --49 + j*(-211) -90 + j*(144) -156 + j*(3) -27 + j*(-264) -302 + j*(23) -148 + j*(-5) --119 + j*(-27) --100 + j*(-138) --182 + j*(-56) --303 + j*(333) --101 + j*(162) -311 + j*(-143) --27 + j*(-283) --215 + j*(-93) --64 + j*(120) --10 + j*(-337) --204 + j*(48) --91 + j*(-95) -113 + j*(-223) --68 + j*(-86) -91 + j*(-162) -383 + j*(534) -331 + j*(-151) -296 + j*(-125) --534 + j*(195) -68 + j*(341) --64 + j*(338) -202 + j*(199) -277 + j*(-187) -10 + j*(-149) --89 + j*(-287) -356 + j*(-535) -136 + j*(225) -221 + j*(-13) -245 + j*(105) --55 + j*(-260) --246 + j*(-332) --146 + j*(315) --602 + j*(-237) --329 + j*(238) --173 + j*(-174) -562 + j*(83) --189 + j*(-310) -339 + j*(361) --309 + j*(-162) -81 + j*(317) -445 + j*(-265) --183 + j*(343) --302 + j*(33) --663 + j*(180) --257 + j*(-70) -515 + j*(252) -192 + j*(334) --560 + j*(68) -214 + j*(11) --463 + j*(-437) -66 + j*(286) --305 + j*(236) --332 + j*(40) --180 + j*(-321) -420 + j*(-76) -63 + j*(-168) -243 + j*(-251) -176 + j*(-378) -328 + j*(303) --270 + j*(353) --407 + j*(-240) -257 + j*(207) --107 + j*(-203) --100 + j*(-153) -635 + j*(335) -45 + j*(52) -251 + j*(-25) -238 + j*(232) --268 + j*(-144) -183 + j*(-70) --237 + j*(-222) -231 + j*(274) --132 + j*(372) -383 + j*(50) --187 + j*(195) -81 + j*(156) --145 + j*(-689) -139 + j*(312) --162 + j*(419) -387 + j*(-187) --168 + j*(-233) --344 + j*(184) --337 + j*(-478) -737 + j*(-88) --106 + j*(486) -44 + j*(226) --293 + j*(100) -532 + j*(-33) -534 + j*(-52) --527 + j*(431) --438 + j*(-312) -223 + j*(-175) -149 + j*(367) -132 + j*(-694) -406 + j*(306) -222 + j*(-339) --68 + j*(493) -348 + j*(123) -16 + j*(-402) -125 + j*(-231) --468 + j*(-245) -304 + j*(74) -439 + j*(423) --438 + j*(18) --686 + j*(327) --150 + j*(98) -303 + j*(147) -411 + j*(-9) --298 + j*(103) --185 + j*(-97) --288 + j*(-369) -393 + j*(-370) -491 + j*(433) -412 + j*(146) --167 + j*(-435) -199 + j*(-350) -316 + j*(-90) -204 + j*(-154) --333 + j*(-12) -682 + j*(-197) --139 + j*(439) --306 + j*(49) --281 + j*(-679) -454 + j*(-212) -444 + j*(508) -106 + j*(-67) --122 + j*(-80) -268 + j*(196) -587 + j*(-342) --275 + j*(379) -443 + j*(-190) --606 + j*(199) --108 + j*(524) --202 + j*(201) --395 + j*(-388) -511 + j*(-591) --265 + j*(-98) -224 + j*(189) -231 + j*(-250) -45 + j*(-397) --286 + j*(-167) -230 + j*(40) -346 + j*(395) --400 + j*(635) -43 + j*(-228) -397 + j*(149) --160 + j*(520) -204 + j*(213) -335 + j*(398) -344 + j*(504) --11 + j*(-309) -59 + j*(-37) --390 + j*(-374) --361 + j*(518) -386 + j*(131) -233 + j*(-187) -356 + j*(23) --157 + j*(-261) --451 + j*(-523) -167 + j*(593) -209 + j*(119) --730 + j*(-56) --219 + j*(-598) -29 + j*(250) -79 + j*(392) -300 + j*(158) -276 + j*(-165) -72 + j*(-346) --245 + j*(-170) -455 + j*(-394) -48 + j*(315) -33 + j*(-81) -201 + j*(127) --37 + j*(51) -196 + j*(180) --62 + j*(416) -267 + j*(252) --242 + j*(-452) --8 + j*(397) -124 + j*(40) --264 + j*(-126) -42 + j*(404) -558 + j*(103) --327 + j*(35) --510 + j*(528) --561 + j*(-597) --349 + j*(-397) -41 + j*(214) --334 + j*(462) -98 + j*(-105) --75 + j*(229) -245 + j*(-116) -330 + j*(186) --81 + j*(434) -488 + j*(200) --124 + j*(-164) --8 + j*(68) --88 + j*(373) --312 + j*(-402) -103 + j*(267) -683 + j*(217) --341 + j*(67) --280 + j*(350) -492 + j*(-231) --211 + j*(-218) -240 + j*(316) -364 + j*(272) -370 + j*(453) -253 + j*(171) -184 + j*(663) --333 + j*(-392) --192 + j*(-409) -384 + j*(-292) -220 + j*(-143) --284 + j*(242) -118 + j*(-272) -170 + j*(-47) -422 + j*(-353) -494 + j*(-685) --88 + j*(95) -264 + j*(232) -153 + j*(175) -168 + j*(205) --126 + j*(-213) --51 + j*(390) --283 + j*(40) --361 + j*(689) -171 + j*(-141) -435 + j*(-318) --141 + j*(-260) -220 + j*(-144) -286 + j*(155) --310 + j*(299) -78 + j*(-204) -373 + j*(273) --321 + j*(723) -707 + j*(-203) -324 + j*(102) --177 + j*(-383) -245 + j*(-99) --380 + j*(339) -235 + j*(-375) --292 + j*(77) -23 + j*(-351) -330 + j*(-171) -211 + j*(167) -455 + j*(-540) --448 + j*(-230) -215 + j*(263) -137 + j*(373) --66 + j*(-47) --300 + j*(-85) -302 + j*(177) --442 + j*(197) --46 + j*(132) --419 + j*(214) --166 + j*(92) --184 + j*(447) -94 + j*(342) --328 + j*(-42) --552 + j*(-458) -374 + j*(-177) -300 + j*(404) -40 + j*(219) --228 + j*(-505) -272 + j*(266) --192 + j*(200) -213 + j*(-150) -274 + j*(-355) -492 + j*(54) -541 + j*(-602) -460 + j*(-52) -98 + j*(449) -382 + j*(-380) --153 + j*(-241) --250 + j*(-45) --245 + j*(-315) -264 + j*(-289) -154 + j*(-177) -146 + j*(-441) --336 + j*(285) --102 + j*(388) -236 + j*(-18) --115 + j*(335) --532 + j*(421) -484 + j*(450) -354 + j*(738) --416 + j*(523) --293 + j*(-193) -115 + j*(-764) --327 + j*(-238) --425 + j*(-378) --269 + j*(-413) --642 + j*(-380) --43 + j*(-7) -206 + j*(424) -244 + j*(-416) -453 + j*(-545) --165 + j*(-64) --138 + j*(-312) --499 + j*(484) --307 + j*(-119) -122 + j*(578) --266 + j*(-390) --218 + j*(395) --188 + j*(-14) -373 + j*(-118) -86 + j*(629) --435 + j*(-107) -390 + j*(-469) -197 + j*(-99) -343 + j*(-344) --137 + j*(-218) --252 + j*(354) --261 + j*(329) --214 + j*(393) --247 + j*(274) -214 + j*(158) -74 + j*(315) -434 + j*(-211) --228 + j*(-161) --86 + j*(482) -41 + j*(197) --110 + j*(217) -182 + j*(16) -437 + j*(-583) -446 + j*(-162) --139 + j*(122) -117 + j*(368) -173 + j*(179) -245 + j*(-228) -78 + j*(450) --484 + j*(-112) --375 + j*(-177) --265 + j*(-155) -185 + j*(-10) -635 + j*(-213) --59 + j*(223) -306 + j*(-93) -8 + j*(-310) -201 + j*(333) -482 + j*(-70) --78 + j*(115) -390 + j*(564) -433 + j*(280) -52 + j*(25) -185 + j*(328) -273 + j*(-367) --156 + j*(255) -177 + j*(-170) --181 + j*(207) --466 + j*(-256) --279 + j*(-97) -444 + j*(-466) --105 + j*(308) -71 + j*(-127) --1 + j*(6) -171 + j*(163) --357 + j*(440) -346 + j*(97) --366 + j*(-355) --149 + j*(-342) --72 + j*(-146) -120 + j*(185) -190 + j*(237) --53 + j*(-444) -340 + j*(68) -103 + j*(7) -210 + j*(183) -282 + j*(-173) -240 + j*(373) --112 + j*(463) --187 + j*(262) --260 + j*(-234) --33 + j*(217) --347 + j*(2) -229 + j*(-414) -163 + j*(284) -121 + j*(61) --286 + j*(439) -403 + j*(112) --290 + j*(122) -339 + j*(151) -339 + j*(-290) -349 + j*(-248) --403 + j*(315) --318 + j*(-601) --293 + j*(-348) -279 + j*(-15) -79 + j*(-222) --458 + j*(-433) -625 + j*(-496) --81 + j*(204) --222 + j*(-499) --486 + j*(-186) --113 + j*(-105) --199 + j*(-497) -351 + j*(174) -347 + j*(-373) -233 + j*(49) --64 + j*(-416) -264 + j*(-139) -33 + j*(494) -281 + j*(180) --412 + j*(-375) --318 + j*(502) --265 + j*(274) --260 + j*(175) -167 + j*(-491) -647 + j*(236) --25 + j*(238) --326 + j*(-495) -100 + j*(-313) -173 + j*(-786) --98 + j*(231) --238 + j*(409) -361 + j*(-446) -538 + j*(-350) --127 + j*(-153) --576 + j*(-199) --72 + j*(-510) -363 + j*(-360) --482 + j*(-238) --352 + j*(-363) --295 + j*(-104) --119 + j*(212) -297 + j*(351) --268 + j*(-371) -97 + j*(53) -235 + j*(90) -209 + j*(298) --212 + j*(-276) --309 + j*(551) --54 + j*(-273) -225 + j*(457) -37 + j*(-149) --81 + j*(202) -345 + j*(300) --322 + j*(247) -202 + j*(425) --215 + j*(-173) --123 + j*(297) --227 + j*(19) --170 + j*(-366) -344 + j*(-305) -369 + j*(-191) --318 + j*(525) -332 + j*(-325) --337 + j*(-318) --655 + j*(564) -595 + j*(-511) -436 + j*(384) --515 + j*(40) -243 + j*(-459) --21 + j*(156) -258 + j*(-438) --357 + j*(-326) --433 + j*(583) --357 + j*(-489) -171 + j*(-34) -122 + j*(402) --289 + j*(339) -160 + j*(189) -94 + j*(-71) -453 + j*(-301) -292 + j*(-117) -338 + j*(216) -363 + j*(400) --43 + j*(-35) -217 + j*(85) -33 + j*(241) -173 + j*(-141) --266 + j*(-306) --264 + j*(-451) -226 + j*(-296) -350 + j*(-16) -30 + j*(312) --566 + j*(-133) --195 + j*(219) -478 + j*(-61) --612 + j*(-527) --189 + j*(-585) --466 + j*(-600) --288 + j*(445) --460 + j*(245) -171 + j*(-448) --258 + j*(520) --379 + j*(-194) -369 + j*(-410) --213 + j*(144) -128 + j*(-40) -308 + j*(277) --37 + j*(-508) -226 + j*(-127) -290 + j*(285) --506 + j*(-353) --356 + j*(-194) -298 + j*(307) -161 + j*(499) -267 + j*(157) -117 + j*(-136) -494 + j*(-658) -103 + j*(-286) -415 + j*(465) -233 + j*(-156) -110 + j*(-371) --428 + j*(196) --377 + j*(269) --234 + j*(127) --321 + j*(-78) -282 + j*(-223) --310 + j*(-246) -45 + j*(146) -5 + j*(38) --182 + j*(239) --430 + j*(453) -414 + j*(-105) --527 + j*(147) --12 + j*(554) --296 + j*(-168) --147 + j*(-170) --504 + j*(-331) --313 + j*(-380) -453 + j*(429) --463 + j*(-119) --175 + j*(-387) -251 + j*(403) --143 + j*(187) -208 + j*(-498) -434 + j*(-214) -600 + j*(-360) --251 + j*(28) -373 + j*(-204) --305 + j*(-288) --243 + j*(356) -53 + j*(-467) -127 + j*(226) --412 + j*(-91) -325 + j*(371) -347 + j*(-487) -332 + j*(327) --226 + j*(-306) -482 + j*(-47) --62 + j*(397) -363 + j*(-184) -192 + j*(257) --390 + j*(-347) --15 + j*(-159) -434 + j*(-467) -347 + j*(-162) -374 + j*(-216) --197 + j*(-21) -195 + j*(679) -317 + j*(451) -206 + j*(400) -420 + j*(421) --190 + j*(-107) --141 + j*(192) -452 + j*(364) --550 + j*(44) --141 + j*(-274) --459 + j*(409) -466 + j*(-351) --178 + j*(103) --378 + j*(351) --213 + j*(132) --322 + j*(102) --244 + j*(-537) --252 + j*(-467) --266 + j*(483) -433 + j*(-273) --180 + j*(-474) -69 + j*(-356) -412 + j*(-295) --36 + j*(-529) --588 + j*(194) --10 + j*(-25) --446 + j*(-204) --380 + j*(1) --481 + j*(-128) --271 + j*(151) --303 + j*(-184) -272 + j*(-253) -102 + j*(284) --153 + j*(66) -100 + j*(-302) -385 + j*(-581) -259 + j*(605) -205 + j*(-482) --288 + j*(-276) -197 + j*(-288) --398 + j*(325) -358 + j*(-357) -104 + j*(-474) -735 + j*(38) -306 + j*(-162) -121 + j*(-267) --480 + j*(272) --13 + j*(-94) --146 + j*(131) --484 + j*(-257) --64 + j*(227) -178 + j*(19) -212 + j*(450) -17 + j*(-184) --406 + j*(-301) --424 + j*(252) --194 + j*(444) --550 + j*(-138) -361 + j*(424) --308 + j*(-156) --251 + j*(-183) -293 + j*(-98) --271 + j*(249) --317 + j*(-79) --42 + j*(276) --88 + j*(217) -1 + j*(327) --53 + j*(250) --42 + j*(-334) -154 + j*(70) -262 + j*(-33) --1 + j*(-104) -35 + j*(-118) -57 + j*(455) -247 + j*(-148) -0 + j*(62) --200 + j*(193) -62 + j*(-139) -95 + j*(111) -291 + j*(-154) --135 + j*(118) -66 + j*(-148) --337 + j*(192) --247 + j*(-26) --13 + j*(-40) --412 + j*(-91) --66 + j*(-206) -91 + j*(179) --189 + j*(407) --152 + j*(35) -187 + j*(28) -206 + j*(7) -242 + j*(-28) --71 + j*(-75) --187 + j*(-48) -240 + j*(-105) --122 + j*(-187) --156 + j*(163) -225 + j*(102) -52 + j*(198) --62 + j*(3) -171 + j*(-147) --84 + j*(-253) --1 + j*(-402) -264 + j*(140) --2 + j*(-152) -75 + j*(-168) --134 + j*(-34) -45 + j*(155) --164 + j*(135) -334 + j*(281) --71 + j*(-170) -296 + j*(-413) -44 + j*(260) -197 + j*(204) -71 + j*(2) -119 + j*(-129) -169 + j*(68) --196 + j*(198) -170 + j*(-124) --120 + j*(-8) -102 + j*(-120) --578 + j*(93) -71 + j*(239) --218 + j*(91) --206 + j*(9) --287 + j*(-461) --260 + j*(-65) -28 + j*(-45) --26 + j*(132) --86 + j*(-8) -0 + j*(-16) --86 + j*(499) --49 + j*(352) -14 + j*(108) -299 + j*(-55) --255 + j*(-81) --375 + j*(228) --125 + j*(66) --107 + j*(159) --199 + j*(-283) -158 + j*(-206) -241 + j*(-91) --44 + j*(4) --288 + j*(127) --19 + j*(-119) -83 + j*(-223) -76 + j*(-191) --19 + j*(64) -205 + j*(-267) -209 + j*(100) -290 + j*(175) -96 + j*(12) -71 + j*(15) -231 + j*(70) -127 + j*(-37) --153 + j*(195) -29 + j*(189) --30 + j*(-94) --55 + j*(-209) -338 + j*(-214) -122 + j*(-64) --234 + j*(172) -160 + j*(-110) -142 + j*(114) -157 + j*(136) --189 + j*(-197) -28 + j*(-45) --42 + j*(-143) -171 + j*(-12) --168 + j*(163) --199 + j*(194) --265 + j*(-212) -181 + j*(-21) --267 + j*(-224) --191 + j*(110) --77 + j*(-215) -83 + j*(-106) --52 + j*(451) --60 + j*(92) --171 + j*(-199) -233 + j*(-231) --107 + j*(39) -151 + j*(42) -120 + j*(-6) --257 + j*(-182) -110 + j*(-52) --208 + j*(-26) --130 + j*(-157) -153 + j*(267) -494 + j*(-45) -178 + j*(-91) --59 + j*(-184) -137 + j*(318) --315 + j*(254) --264 + j*(-67) -42 + j*(-4) -102 + j*(62) --43 + j*(-23) --132 + j*(79) --163 + j*(-138) --132 + j*(-232) -106 + j*(50) -264 + j*(56) --172 + j*(-100) -318 + j*(147) -84 + j*(-246) -274 + j*(-330) -177 + j*(19) -185 + j*(81) -201 + j*(18) --306 + j*(110) -81 + j*(-6) -65 + j*(-186) --278 + j*(-66) -175 + j*(55) -8 + j*(107) --85 + j*(14) -300 + j*(395) --65 + j*(-403) -293 + j*(-56) --187 + j*(103) -66 + j*(-240) -66 + j*(-302) --82 + j*(-214) -194 + j*(-47) -64 + j*(-235) --372 + j*(-222) -119 + j*(-341) --323 + j*(40) --114 + j*(293) --208 + j*(-158) --95 + j*(183) -161 + j*(231) -47 + j*(-131) -102 + j*(-31) -205 + j*(-180) --40 + j*(-127) -175 + j*(-288) -79 + j*(-272) --245 + j*(3) -251 + j*(-3) --119 + j*(243) --123 + j*(-339) --290 + j*(85) --100 + j*(-175) --205 + j*(477) --24 + j*(-71) -342 + j*(-185) -66 + j*(13) --56 + j*(78) -175 + j*(-124) --228 + j*(117) --122 + j*(-62) -72 + j*(308) -222 + j*(-223) -85 + j*(47) --59 + j*(173) --97 + j*(142) -141 + j*(-108) --278 + j*(107) --141 + j*(75) -211 + j*(74) -319 + j*(-107) --98 + j*(209) --350 + j*(45) --468 + j*(-308) -332 + j*(-157) --10 + j*(-57) -21 + j*(-37) -1 + j*(-71) -151 + j*(18) --356 + j*(361) -7 + j*(-8) --87 + j*(-148) -205 + j*(-86) --9 + j*(85) -419 + j*(64) -80 + j*(60) -199 + j*(197) --187 + j*(-205) --119 + j*(228) -11 + j*(187) --212 + j*(-21) --160 + j*(121) -45 + j*(-420) --158 + j*(-173) -49 + j*(286) -204 + j*(54) -158 + j*(206) --1 + j*(-63) -119 + j*(9) -169 + j*(-116) -325 + j*(145) --106 + j*(6) --96 + j*(44) --140 + j*(253) -138 + j*(23) --431 + j*(-37) --72 + j*(5) --35 + j*(128) --165 + j*(75) --45 + j*(-158) -298 + j*(119) -105 + j*(119) -162 + j*(-16) -64 + j*(-173) --269 + j*(37) -110 + j*(-21) --16 + j*(30) -113 + j*(129) --164 + j*(-238) --189 + j*(62) -66 + j*(-142) -418 + j*(20) --264 + j*(-245) --251 + j*(76) -24 + j*(-4) -310 + j*(-84) --112 + j*(-76) --20 + j*(27) -270 + j*(-126) --241 + j*(46) --258 + j*(123) --195 + j*(-302) -294 + j*(-168) -83 + j*(-46) --121 + j*(-111) --297 + j*(-122) --269 + j*(32) --171 + j*(-107) --89 + j*(336) --180 + j*(-263) --163 + j*(-48) -265 + j*(-103) -33 + j*(22) -448 + j*(99) --49 + j*(85) -259 + j*(-72) -13 + j*(7) --156 + j*(11) --112 + j*(186) -91 + j*(-44) -127 + j*(110) -190 + j*(-151) -26 + j*(-373) -115 + j*(177) -99 + j*(-327) -60 + j*(-87) --42 + j*(-71) -80 + j*(132) -173 + j*(276) -6 + j*(177) -46 + j*(-154) -6 + j*(115) -132 + j*(156) --303 + j*(257) -105 + j*(-506) -293 + j*(82) -23 + j*(62) --563 + j*(397) -308 + j*(17) --16 + j*(-53) --22 + j*(-210) -256 + j*(190) --40 + j*(308) -181 + j*(37) --179 + j*(-71) --42 + j*(37) --258 + j*(375) --81 + j*(115) --59 + j*(287) --66 + j*(122) --1 + j*(-218) -258 + j*(-6) -78 + j*(-95) -97 + j*(-148) --255 + j*(165) -226 + j*(0) -39 + j*(-141) -175 + j*(111) -21 + j*(110) --93 + j*(288) --240 + j*(-11) --163 + j*(77) -25 + j*(110) -70 + j*(78) -51 + j*(425) --74 + j*(-186) -121 + j*(-54) -270 + j*(64) -115 + j*(-173) --143 + j*(281) -88 + j*(-247) --20 + j*(-112) -156 + j*(-362) -33 + j*(-128) -97 + j*(-328) -28 + j*(-41) -58 + j*(47) -45 + j*(13) -206 + j*(560) -94 + j*(-16) -81 + j*(41) -270 + j*(13) -68 + j*(95) --33 + j*(-120) --173 + j*(-166) --64 + j*(124) -17 + j*(-88) -99 + j*(13) --380 + j*(6) --65 + j*(219) --16 + j*(-51) -35 + j*(146) -138 + j*(74) -453 + j*(-59) -337 + j*(-5) --218 + j*(-105) --360 + j*(-43) -99 + j*(-1) --12 + j*(-76) --183 + j*(221) -52 + j*(13) -86 + j*(-76) --265 + j*(-12) -61 + j*(-264) --29 + j*(91) -20 + j*(-177) -89 + j*(-281) -276 + j*(-13) -243 + j*(-251) --140 + j*(-55) -173 + j*(23) --14 + j*(-109) -59 + j*(57) -238 + j*(-78) -50 + j*(124) -132 + j*(70) --358 + j*(21) --228 + j*(51) --16 + j*(-243) --40 + j*(267) -49 + j*(231) -309 + j*(8) -32 + j*(-109) --147 + j*(190) -232 + j*(-166) --190 + j*(-117) -18 + j*(-43) --54 + j*(129) -145 + j*(110) --202 + j*(-232) --16 + j*(64) --320 + j*(354) -69 + j*(-96) --233 + j*(165) --93 + j*(-98) --182 + j*(-310) -144 + j*(-146) -192 + j*(6) -112 + j*(146) -214 + j*(352) --153 + j*(44) --218 + j*(-5) --76 + j*(110) -18 + j*(-194) --23 + j*(-85) --4 + j*(-256) -8 + j*(1) -49 + j*(111) --108 + j*(-100) --47 + j*(214) --72 + j*(143) --351 + j*(212) --51 + j*(62) --96 + j*(173) --56 + j*(-223) -101 + j*(-143) -245 + j*(-344) --74 + j*(103) -381 + j*(-153) -76 + j*(271) --126 + j*(-9) -62 + j*(90) -72 + j*(459) --132 + j*(-227) --57 + j*(161) --294 + j*(48) --158 + j*(65) --154 + j*(-49) -21 + j*(156) --289 + j*(226) -45 + j*(79) --156 + j*(61) -50 + j*(15) --368 + j*(-200) --202 + j*(64) -344 + j*(190) -31 + j*(139) -101 + j*(95) --446 + j*(74) -254 + j*(-9) -175 + j*(28) --158 + j*(115) --173 + j*(-316) --88 + j*(-179) --18 + j*(-386) -112 + j*(144) --368 + j*(250) --233 + j*(-171) --165 + j*(16) --188 + j*(71) --41 + j*(-57) -422 + j*(47) -62 + j*(-120) -18 + j*(4) --103 + j*(-131) --21 + j*(-190) --205 + j*(-158) -268 + j*(151) --250 + j*(156) --142 + j*(-12) -99 + j*(237) -363 + j*(78) -108 + j*(-13) -291 + j*(-148) --243 + j*(486) -177 + j*(33) -117 + j*(15) --126 + j*(-1) --185 + j*(-149) -115 + j*(108) -1 + j*(-47) -58 + j*(-262) -275 + j*(-234) --83 + j*(155) -291 + j*(72) --187 + j*(147) -57 + j*(14) -25 + j*(280) -318 + j*(23) --229 + j*(223) -164 + j*(86) -293 + j*(100) --52 + j*(-40) -87 + j*(118) --8 + j*(4) -134 + j*(47) -250 + j*(376) --73 + j*(64) -104 + j*(-39) --305 + j*(-147) --419 + j*(-16) --41 + j*(8) --83 + j*(-453) --19 + j*(201) --124 + j*(-91) --175 + j*(-139) -25 + j*(144) --28 + j*(303) --339 + j*(57) --139 + j*(319) --141 + j*(11) --109 + j*(-14) --6 + j*(-254) --8 + j*(80) -319 + j*(101) -94 + j*(-40) --202 + j*(-161) --329 + j*(-263) --115 + j*(-208) -250 + j*(-221) -214 + j*(29) -297 + j*(-151) -21 + j*(-16) -3 + j*(204) -8 + j*(-18) -302 + j*(-215) --216 + j*(-25) --54 + j*(-63) --113 + j*(-21) --218 + j*(-19) -102 + j*(-134) -303 + j*(-272) --199 + j*(-87) --115 + j*(-137) --52 + j*(16) --153 + j*(-173) -228 + j*(428) --43 + j*(-187) -149 + j*(-149) --83 + j*(373) --158 + j*(512) --306 + j*(64) --59 + j*(54) --94 + j*(-110) -240 + j*(-116) -99 + j*(52) -262 + j*(-194) --152 + j*(85) --105 + j*(218) --30 + j*(-55) -187 + j*(98) -308 + j*(-119) -54 + j*(-221) -103 + j*(175) -16 + j*(129) -149 + j*(-23) -95 + j*(7) --267 + j*(-37) -2 + j*(283) --237 + j*(30) --28 + j*(-204) -18 + j*(10) --25 + j*(-262) --252 + j*(45) --7 + j*(64) -139 + j*(325) --44 + j*(-243) --94 + j*(194) -132 + j*(192) -74 + j*(-332) -212 + j*(-189) --20 + j*(83) -56 + j*(-45) --371 + j*(-122) -10 + j*(134) --163 + j*(69) --305 + j*(35) -27 + j*(-186) -106 + j*(54) -226 + j*(8) --185 + j*(50) --3 + j*(-26) -11 + j*(136) --360 + j*(-132) -192 + j*(-67) -189 + j*(-46) --23 + j*(122) --119 + j*(-45) -187 + j*(-186) -24 + j*(78) -21 + j*(-125) -433 + j*(-60) -180 + j*(-35) --166 + j*(3) -44 + j*(134) -79 + j*(26) --82 + j*(103) --180 + j*(-40) -11 + j*(49) -147 + j*(132) -10 + j*(-36) -53 + j*(-157) -170 + j*(163) -71 + j*(213) -82 + j*(-135) --56 + j*(-138) -41 + j*(-115) --190 + j*(-4) -55 + j*(199) --144 + j*(-113) --397 + j*(-207) --165 + j*(-22) -46 + j*(122) --151 + j*(-102) -124 + j*(-79) -1 + j*(-262) -313 + j*(-66) -117 + j*(54) -110 + j*(-117) --254 + j*(-152) --2 + j*(-24) --199 + j*(25) --178 + j*(-133) --164 + j*(88) --18 + j*(-30) --166 + j*(83) -18 + j*(-286) -230 + j*(100) -153 + j*(-115) -49 + j*(-59) --39 + j*(-12) --412 + j*(-168) --151 + j*(293) -81 + j*(-356) -106 + j*(11) -101 + j*(-76) --103 + j*(489) -60 + j*(327) --254 + j*(-398) --96 + j*(-74) -115 + j*(-133) --114 + j*(91) -105 + j*(23) --334 + j*(-8) -421 + j*(-191) --281 + j*(-4) -49 + j*(-26) -83 + j*(-13) -102 + j*(202) -115 + j*(214) --18 + j*(322) -201 + j*(161) -34 + j*(-37) --204 + j*(181) -412 + j*(-41) -187 + j*(-15) --11 + j*(95) --8 + j*(-322) --364 + j*(40) --148 + j*(-52) -351 + j*(-114) -244 + j*(175) --123 + j*(-182) --59 + j*(-103) --60 + j*(98) --166 + j*(83) --192 + j*(71) --187 + j*(223) --24 + j*(-272) -209 + j*(-320) --45 + j*(-89) -438 + j*(-54) --64 + j*(-235) --346 + j*(-112) --12 + j*(142) --331 + j*(-138) -78 + j*(-123) --274 + j*(28) --6 + j*(-132) --64 + j*(258) -159 + j*(-135) -146 + j*(-85) --69 + j*(-122) -12 + j*(394) --24 + j*(-233) -194 + j*(144) -105 + j*(-107) -47 + j*(33) -30 + j*(-122) --27 + j*(-21) --48 + j*(-248) -354 + j*(91) --3 + j*(54) --440 + j*(-37) --127 + j*(198) -99 + j*(-142) -252 + j*(139) --150 + j*(-184) --355 + j*(-5) -192 + j*(243) --107 + j*(259) --95 + j*(81) --345 + j*(40) --207 + j*(-141) -47 + j*(76) --118 + j*(66) --161 + j*(128) --1 + j*(186) --45 + j*(-187) -106 + j*(224) --48 + j*(-237) -35 + j*(-229) --55 + j*(-293) --54 + j*(-86) --183 + j*(79) --15 + j*(-41) --122 + j*(231) -69 + j*(-17) -100 + j*(279) -320 + j*(76) --68 + j*(-83) -107 + j*(-70) --94 + j*(158) --93 + j*(122) --141 + j*(22) -65 + j*(91) --390 + j*(-91) --216 + j*(35) -37 + j*(-191) --57 + j*(14) -57 + j*(-288) -378 + j*(344) -42 + j*(448) -38 + j*(66) --76 + j*(-260) -298 + j*(-250) -13 + j*(-370) -156 + j*(-169) -72 + j*(-215) -173 + j*(289) -194 + j*(130) --23 + j*(202) --22 + j*(298) -148 + j*(-113) --131 + j*(-168) -339 + j*(107) -172 + j*(245) --136 + j*(-105) --186 + j*(-156) --67 + j*(221) --139 + j*(-42) -151 + j*(247) --13 + j*(24) -41 + j*(139) --165 + j*(185) --55 + j*(-143) -35 + j*(-252) --148 + j*(349) --147 + j*(-26) -36 + j*(-332) --58 + j*(-306) --152 + j*(107) -157 + j*(-163) --195 + j*(68) -241 + j*(282) -18 + j*(-115) -211 + j*(-32) -185 + j*(309) --76 + j*(122) -114 + j*(6) --58 + j*(-52) --161 + j*(-116) -6 + j*(159) -141 + j*(173) --134 + j*(-146) --243 + j*(250) -38 + j*(221) --122 + j*(-24) --37 + j*(454) --119 + j*(-127) -122 + j*(-71) -52 + j*(-101) -63 + j*(-133) -8 + j*(-279) -214 + j*(-154) --467 + j*(110) -78 + j*(6) --216 + j*(-87) --147 + j*(-160) --38 + j*(161) -124 + j*(245) --56 + j*(-250) --70 + j*(-132) --235 + j*(117) --25 + j*(36) -67 + j*(-18) -115 + j*(-83) -88 + j*(278) --175 + j*(-8) -285 + j*(-65) -29 + j*(-49) --42 + j*(-153) --23 + j*(-26) -153 + j*(-66) --218 + j*(251) --37 + j*(228) --21 + j*(30) -101 + j*(-76) --5 + j*(-206) -49 + j*(37) --100 + j*(-129) -3 + j*(-216) -9 + j*(49) -247 + j*(13) --20 + j*(99) --19 + j*(134) --2 + j*(144) -153 + j*(112) -362 + j*(91) --74 + j*(-28) -211 + j*(-182) -105 + j*(226) --100 + j*(130) -37 + j*(16) -130 + j*(167) --88 + j*(-218) -143 + j*(84) -31 + j*(35) -212 + j*(390) -1 + j*(-293) --12 + j*(-161) --49 + j*(-143) --91 + j*(-130) -6 + j*(-74) --59 + j*(185) --177 + j*(92) --19 + j*(25) --232 + j*(-138) -110 + j*(103) --40 + j*(131) -3 + j*(-152) --55 + j*(105) -260 + j*(-247) -286 + j*(-23) -98 + j*(-16) -54 + j*(33) --358 + j*(-16) --146 + j*(107) --249 + j*(-199) --158 + j*(87) --72 + j*(-110) -133 + j*(-196) --141 + j*(354) -71 + j*(-152) -159 + j*(192) --162 + j*(62) -182 + j*(344) --2 + j*(14) --293 + j*(321) --41 + j*(-82) --24 + j*(225) --17 + j*(-158) --37 + j*(103) -42 + j*(-50) --33 + j*(229) --22 + j*(54) --105 + j*(-125) -343 + j*(298) --211 + j*(231) -75 + j*(-85) -181 + j*(-33) -194 + j*(205) --36 + j*(103) --325 + j*(-103) --148 + j*(-293) --143 + j*(-52) --294 + j*(16) --147 + j*(-192) --132 + j*(64) --75 + j*(-105) --279 + j*(-113) -15 + j*(-10) -103 + j*(-361) -45 + j*(315) --8 + j*(-119) --352 + j*(-97) --8 + j*(-74) --363 + j*(112) --196 + j*(67) -226 + j*(-40) -235 + j*(117) --140 + j*(47) -33 + j*(161) -149 + j*(162) --468 + j*(-17) --270 + j*(-72) --335 + j*(-178) --23 + j*(184) -156 + j*(361) -184 + j*(177) -151 + j*(141) --100 + j*(-231) --2 + j*(71) --3 + j*(103) -230 + j*(105) -50 + j*(306) --194 + j*(216) -101 + j*(-252) --187 + j*(88) --114 + j*(43) -6 + j*(124) --143 + j*(-50) --237 + j*(33) -115 + j*(144) --112 + j*(-465) -86 + j*(-54) --125 + j*(-146) -127 + j*(-179) -175 + j*(-162) -146 + j*(-141) --272 + j*(-158) -107 + j*(168) -48 + j*(143) --42 + j*(-18) -33 + j*(83) --213 + j*(269) -58 + j*(-211) --140 + j*(100) -29 + j*(-171) -311 + j*(-104) --13 + j*(127) --55 + j*(110) --191 + j*(4) --16 + j*(93) --338 + j*(255) -103 + j*(55) --88 + j*(-111) -41 + j*(49) -191 + j*(124) -145 + j*(163) -18 + j*(-132) --46 + j*(81) --59 + j*(-154) -277 + j*(179) -199 + j*(104) -40 + j*(4) --46 + j*(28) --13 + j*(-26) -89 + j*(11) --56 + j*(91) --228 + j*(-152) --7 + j*(64) -122 + j*(-274) -151 + j*(-303) --273 + j*(-251) --60 + j*(264) -49 + j*(-74) --56 + j*(-255) -445 + j*(210) -33 + j*(-155) --271 + j*(-182) --36 + j*(-136) -8 + j*(-16) --204 + j*(-123) --124 + j*(33) --139 + j*(32) -90 + j*(-192) -282 + j*(83) -48 + j*(-245) -129 + j*(98) --54 + j*(344) --18 + j*(252) --279 + j*(-146) --115 + j*(-52) -79 + j*(192) -132 + j*(22) --103 + j*(-162) --42 + j*(64) -9 + j*(-185) --132 + j*(-54) -9 + j*(129) -211 + j*(50) --164 + j*(-13) -258 + j*(-100) -194 + j*(145) --420 + j*(-276) -27 + j*(-30) --106 + j*(74) --71 + j*(378) --296 + j*(178) -190 + j*(175) -217 + j*(-64) -455 + j*(-68) -69 + j*(144) -216 + j*(6) -25 + j*(39) -39 + j*(78) --31 + j*(134) -165 + j*(-6) --160 + j*(-95) -185 + j*(-281) -71 + j*(402) --155 + j*(414) -159 + j*(-88) -302 + j*(-307) -73 + j*(-36) --81 + j*(215) -142 + j*(-110) -103 + j*(-156) -195 + j*(-28) -185 + j*(167) --89 + j*(117) --147 + j*(-75) -118 + j*(-332) --7 + j*(104) -211 + j*(-114) -201 + j*(-291) -49 + j*(88) -159 + j*(-75) --327 + j*(-508) -26 + j*(13) --387 + j*(-252) -148 + j*(-234) -23 + j*(-49) -78 + j*(-138) -189 + j*(-103) --20 + j*(117) --33 + j*(6) -149 + j*(-153) --85 + j*(-231) --127 + j*(135) --136 + j*(-206) --73 + j*(69) --134 + j*(7) --264 + j*(-69) --82 + j*(89) --248 + j*(127) -30 + j*(-12) --138 + j*(-164) -123 + j*(-185) -237 + j*(-33) --187 + j*(-103) --115 + j*(-215) -28 + j*(347) -220 + j*(131) -281 + j*(-134) --107 + j*(110) -133 + j*(-53) -204 + j*(132) --85 + j*(289) -235 + j*(-135) --145 + j*(153) --87 + j*(332) --213 + j*(-73) --153 + j*(-220) --214 + j*(-223) -59 + j*(-12) -48 + j*(-79) -11 + j*(8) --46 + j*(-181) -94 + j*(141) -39 + j*(-21) -70 + j*(-293) -145 + j*(13) -32 + j*(-18) -134 + j*(129) --110 + j*(-243) --127 + j*(292) -4 + j*(209) --139 + j*(-44) --21 + j*(-40) -35 + j*(-84) --316 + j*(-268) --195 + j*(166) --95 + j*(-24) -233 + j*(-18) -240 + j*(-88) --66 + j*(-143) -155 + j*(9) -266 + j*(235) --94 + j*(-28) -117 + j*(35) --189 + j*(9) --205 + j*(40) --74 + j*(252) --141 + j*(150) --29 + j*(-57) -49 + j*(103) --57 + j*(251) -109 + j*(95) -284 + j*(-16) -11 + j*(-96) --289 + j*(-351) --6 + j*(-222) -355 + j*(118) --139 + j*(179) --143 + j*(137) -88 + j*(-86) -243 + j*(-131) -117 + j*(-6) --489 + j*(70) -74 + j*(245) -93 + j*(88) --62 + j*(54) -218 + j*(176) --146 + j*(-126) -28 + j*(-53) -86 + j*(13) -203 + j*(153) -150 + j*(74) -200 + j*(320) -95 + j*(142) -58 + j*(156) -345 + j*(-52) --59 + j*(462) --22 + j*(-43) --160 + j*(141) -313 + j*(-104) --190 + j*(-67) -25 + j*(-103) --305 + j*(17) -53 + j*(-52) --36 + j*(-101) --67 + j*(-47) --198 + j*(202) -231 + j*(-218) --62 + j*(146) -68 + j*(-172) --148 + j*(-134) --32 + j*(-184) --378 + j*(88) --248 + j*(12) --37 + j*(-68) -11 + j*(44) --19 + j*(-67) -215 + j*(262) --190 + j*(229) --277 + j*(62) -140 + j*(-204) --219 + j*(-9) -78 + j*(-64) -249 + j*(16) --1 + j*(-115) -58 + j*(276) --94 + j*(-193) -80 + j*(-61) -333 + j*(77) -150 + j*(233) --251 + j*(-255) -0 + j*(340) --205 + j*(-45) -80 + j*(-305) -112 + j*(-45) --28 + j*(-1) --1 + j*(22) -125 + j*(-304) --276 + j*(-24) --28 + j*(-177) -117 + j*(197) -192 + j*(-29) -40 + j*(158) --304 + j*(-122) --84 + j*(-35) -160 + j*(-28) -36 + j*(110) -119 + j*(7) --35 + j*(-127) -8 + j*(33) -161 + j*(48) --65 + j*(158) --237 + j*(-220) --65 + j*(-294) -157 + j*(155) --8 + j*(-296) -18 + j*(-273) -173 + j*(-16) -136 + j*(23) -85 + j*(156) -1 + j*(144) -147 + j*(-281) --95 + j*(94) --69 + j*(-103) -165 + j*(-25) --196 + j*(257) -80 + j*(195) -31 + j*(-11) --267 + j*(-69) --208 + j*(-127) --180 + j*(-87) --90 + j*(48) -69 + j*(-47) --163 + j*(-314) --4 + j*(-166) --45 + j*(460) --5 + j*(-4) -105 + j*(-238) --240 + j*(158) --145 + j*(72) -95 + j*(-35) --4 + j*(-213) -14 + j*(182) --33 + j*(123) --385 + j*(170) -32 + j*(-27) --19 + j*(-164) --245 + j*(68) --16 + j*(-67) -226 + j*(88) --130 + j*(-112) -4 + j*(-4) --320 + j*(54) --154 + j*(-131) -184 + j*(33) -137 + j*(-269) -148 + j*(-68) --93 + j*(-13) -94 + j*(-280) -35 + j*(98) --104 + j*(-165) --71 + j*(-84) -293 + j*(-71) -247 + j*(159) --91 + j*(-63) --95 + j*(246) --124 + j*(49) --158 + j*(227) --146 + j*(-84) --185 + j*(-206) -101 + j*(129) --45 + j*(-361) --140 + j*(115) -8 + j*(-83) --426 + j*(-45) -365 + j*(-120) --115 + j*(98) --247 + j*(192) -23 + j*(39) --22 + j*(205) -30 + j*(40) -196 + j*(-71) --74 + j*(193) -76 + j*(-51) --123 + j*(-93) --37 + j*(-251) --26 + j*(170) --263 + j*(43) --42 + j*(-224) -214 + j*(153) --33 + j*(86) --137 + j*(158) -148 + j*(122) -68 + j*(26) -341 + j*(-75) -121 + j*(96) -74 + j*(-235) -25 + j*(-41) -50 + j*(141) --183 + j*(69) -74 + j*(-94) -119 + j*(-129) -55 + j*(5) --132 + j*(267) --167 + j*(-24) --273 + j*(139) -270 + j*(59) --114 + j*(-62) -46 + j*(63) --74 + j*(42) -378 + j*(-223) -27 + j*(122) -121 + j*(372) -278 + j*(116) --33 + j*(-276) -9 + j*(-49) --403 + j*(138) --5 + j*(342) --109 + j*(-95) --31 + j*(-43) -62 + j*(-186) -163 + j*(-233) --28 + j*(144) -194 + j*(93) -69 + j*(-206) -180 + j*(-120) --72 + j*(-62) --52 + j*(-166) -81 + j*(128) -239 + j*(-315) -30 + j*(-97) -194 + j*(-300) -26 + j*(197) -12 + j*(-54) --13 + j*(146) -322 + j*(55) --341 + j*(-282) -29 + j*(-225) --91 + j*(7) --160 + j*(64) -7 + j*(-127) -28 + j*(-158) --97 + j*(283) --276 + j*(62) --53 + j*(-362) -59 + j*(18) -227 + j*(-390) --86 + j*(132) --105 + j*(-513) --87 + j*(29) -35 + j*(-110) -18 + j*(47) -180 + j*(-45) --112 + j*(5) -44 + j*(-31) --144 + j*(66) --284 + j*(187) --373 + j*(183) -66 + j*(-160) -378 + j*(209) --360 + j*(-33) --181 + j*(-174) -31 + j*(-209) -66 + j*(-187) --224 + j*(-27) --118 + j*(-124) -16 + j*(156) --29 + j*(163) --112 + j*(69) --10 + j*(191) -114 + j*(-103) -8 + j*(16) --132 + j*(105) --221 + j*(211) --187 + j*(-11) -100 + j*(-49) --27 + j*(52) --62 + j*(1) -48 + j*(-86) --243 + j*(296) --307 + j*(-22) -47 + j*(-23) --126 + j*(-111) --93 + j*(-12) --46 + j*(-265) -71 + j*(-1) --52 + j*(42) --180 + j*(344) -78 + j*(-95) --167 + j*(-28) --293 + j*(196) -247 + j*(63) -112 + j*(383) -225 + j*(-232) -97 + j*(-60) --57 + j*(-233) --180 + j*(-136) -130 + j*(-187) --62 + j*(-65) -13 + j*(14) --9 + j*(267) --243 + j*(-458) -21 + j*(267) --57 + j*(-45) --148 + j*(130) -86 + j*(251) --366 + j*(93) --375 + j*(302) -107 + j*(-11) --12 + j*(-207) -198 + j*(-397) --346 + j*(15) --19 + j*(177) -28 + j*(-23) --87 + j*(-81) --164 + j*(-117) --184 + j*(42) --43 + j*(231) --49 + j*(-143) --209 + j*(-252) --344 + j*(171) -261 + j*(200) -210 + j*(2) --78 + j*(18) -120 + j*(-31) --46 + j*(37) -105 + j*(228) -252 + j*(-62) -76 + j*(190) --200 + j*(-88) -112 + j*(31) -97 + j*(46) --14 + j*(191) -122 + j*(70) --110 + j*(132) -52 + j*(-151) --161 + j*(69) -74 + j*(228) --170 + j*(41) --59 + j*(-354) --98 + j*(325) -64 + j*(-64) --235 + j*(175) --230 + j*(-93) -83 + j*(-48) --274 + j*(-86) -133 + j*(-92) --118 + j*(190) --192 + j*(232) -107 + j*(226) --178 + j*(-91) --45 + j*(35) -212 + j*(194) -38 + j*(-66) -2 + j*(142) -156 + j*(296) --62 + j*(38) -34 + j*(-358) --133 + j*(-114) -94 + j*(80) --299 + j*(41) -23 + j*(264) --223 + j*(515) --82 + j*(-98) --180 + j*(175) --160 + j*(-163) --42 + j*(81) --110 + j*(-93) --95 + j*(-186) --182 + j*(-190) -29 + j*(-227) -36 + j*(107) --25 + j*(-239) --147 + j*(-128) -214 + j*(178) --144 + j*(-26) --162 + j*(210) --1 + j*(-170) --182 + j*(76) --214 + j*(272) -209 + j*(112) --335 + j*(199) -202 + j*(93) -192 + j*(-119) --160 + j*(65) -231 + j*(-61) --37 + j*(-151) -77 + j*(114) -293 + j*(34) --203 + j*(-176) --164 + j*(142) --233 + j*(269) --45 + j*(227) -313 + j*(74) --52 + j*(210) --396 + j*(-31) --111 + j*(-95) --11 + j*(83) -112 + j*(246) --59 + j*(95) -196 + j*(121) --364 + j*(-285) -139 + j*(284) --301 + j*(-78) --274 + j*(-334) --413 + j*(-324) -25 + j*(-57) --251 + j*(-60) -552 + j*(-140) -98 + j*(559) -452 + j*(-165) -334 + j*(-16) --477 + j*(-221) --273 + j*(82) --170 + j*(127) -600 + j*(348) -412 + j*(187) -392 + j*(393) -356 + j*(-431) --303 + j*(-270) --383 + j*(388) -107 + j*(-441) --371 + j*(155) -385 + j*(398) --262 + j*(-58) -244 + j*(-265) -494 + j*(359) --245 + j*(214) -141 + j*(-274) -281 + j*(-645) -252 + j*(222) --252 + j*(-163) --350 + j*(371) -143 + j*(-293) --426 + j*(-419) -107 + j*(-83) --183 + j*(-363) -431 + j*(-91) --557 + j*(-171) --7 + j*(576) -393 + j*(-195) --415 + j*(387) -95 + j*(-383) -56 + j*(156) -223 + j*(433) --670 + j*(232) --78 + j*(192) -327 + j*(187) --47 + j*(-198) --47 + j*(379) -158 + j*(-204) -170 + j*(40) -120 + j*(-402) --57 + j*(-609) -363 + j*(197) -572 + j*(240) -159 + j*(277) -51 + j*(594) -284 + j*(-165) --221 + j*(406) --83 + j*(-173) -248 + j*(-268) --106 + j*(67) --233 + j*(330) --208 + j*(-184) -414 + j*(-62) --170 + j*(609) --309 + j*(177) -278 + j*(-119) -611 + j*(251) --67 + j*(438) -354 + j*(87) -344 + j*(225) -388 + j*(190) -386 + j*(273) --235 + j*(-399) -450 + j*(89) --129 + j*(-380) -307 + j*(-317) -6 + j*(454) --21 + j*(683) -382 + j*(607) -26 + j*(269) -397 + j*(394) -525 + j*(-202) --373 + j*(-337) -607 + j*(363) -142 + j*(235) -320 + j*(-230) -276 + j*(223) --82 + j*(-39) --41 + j*(374) -298 + j*(313) --453 + j*(136) --487 + j*(-484) --50 + j*(214) --265 + j*(259) --185 + j*(-32) --268 + j*(6) -335 + j*(414) --385 + j*(-177) --438 + j*(-168) --153 + j*(475) --93 + j*(223) --279 + j*(283) -481 + j*(-119) -2 + j*(-363) -571 + j*(346) -342 + j*(143) --379 + j*(175) --30 + j*(-334) --431 + j*(237) -113 + j*(-408) -420 + j*(-398) --101 + j*(-35) --363 + j*(77) --421 + j*(129) -378 + j*(166) --316 + j*(-40) -402 + j*(-251) -22 + j*(-351) -223 + j*(-376) -273 + j*(599) --213 + j*(30) -269 + j*(-317) -209 + j*(357) --156 + j*(517) -97 + j*(504) -296 + j*(-239) -65 + j*(1) -278 + j*(342) --175 + j*(-567) -325 + j*(-247) --455 + j*(-64) -512 + j*(-163) -148 + j*(542) -183 + j*(273) --224 + j*(53) -327 + j*(256) -124 + j*(-139) -63 + j*(124) --57 + j*(-381) -112 + j*(-13) -269 + j*(-236) --104 + j*(-487) --227 + j*(-422) -434 + j*(-423) -387 + j*(-274) --118 + j*(110) -197 + j*(342) --96 + j*(300) -413 + j*(-33) --184 + j*(-374) -451 + j*(68) -435 + j*(-132) --244 + j*(-332) -482 + j*(296) -500 + j*(-520) -41 + j*(-66) --137 + j*(678) --433 + j*(361) --573 + j*(576) --350 + j*(255) --185 + j*(-711) -491 + j*(403) --203 + j*(-359) -36 + j*(-153) --199 + j*(-299) -312 + j*(-607) -17 + j*(82) --284 + j*(311) --651 + j*(349) --317 + j*(-525) -461 + j*(-175) --272 + j*(-30) --433 + j*(392) --204 + j*(242) --132 + j*(330) -37 + j*(-193) -461 + j*(-472) --188 + j*(-404) -136 + j*(434) -489 + j*(-688) --261 + j*(-331) --79 + j*(323) --181 + j*(-231) -236 + j*(483) -294 + j*(-152) -118 + j*(-52) -286 + j*(299) -353 + j*(-41) --250 + j*(262) --332 + j*(385) --1 + j*(-199) -547 + j*(-29) -135 + j*(307) -150 + j*(348) --211 + j*(386) --124 + j*(-317) -197 + j*(289) -6 + j*(224) --571 + j*(327) --127 + j*(-331) -164 + j*(-490) --211 + j*(428) -507 + j*(99) -1 + j*(-32) --378 + j*(-261) -396 + j*(-520) --180 + j*(332) -318 + j*(119) --143 + j*(364) --177 + j*(527) --141 + j*(47) -180 + j*(104) --38 + j*(-321) -185 + j*(353) --414 + j*(250) -29 + j*(-441) --202 + j*(247) -16 + j*(62) -432 + j*(467) --206 + j*(175) -94 + j*(-132) -321 + j*(369) -705 + j*(170) -346 + j*(512) --368 + j*(-420) -53 + j*(117) -98 + j*(-211) --267 + j*(251) -366 + j*(144) -630 + j*(144) --187 + j*(333) --271 + j*(566) --344 + j*(-87) -437 + j*(316) --181 + j*(423) --280 + j*(90) -497 + j*(226) --191 + j*(-57) -334 + j*(122) --228 + j*(309) -412 + j*(-351) -289 + j*(193) -194 + j*(124) -293 + j*(-198) --175 + j*(343) --222 + j*(-327) -40 + j*(-205) -357 + j*(-335) --131 + j*(-187) -5 + j*(-491) -38 + j*(330) -6 + j*(274) -207 + j*(113) --339 + j*(-238) -245 + j*(-246) --46 + j*(-59) --375 + j*(-393) --231 + j*(515) -53 + j*(262) --224 + j*(190) --363 + j*(-43) -224 + j*(150) -122 + j*(-337) --296 + j*(-264) -73 + j*(445) --217 + j*(359) --270 + j*(-305) --342 + j*(526) -286 + j*(-655) --216 + j*(410) -606 + j*(368) -540 + j*(347) --66 + j*(-136) -149 + j*(342) -64 + j*(-315) --483 + j*(-236) --313 + j*(-325) --150 + j*(238) --175 + j*(-165) --239 + j*(409) -166 + j*(-18) -282 + j*(-151) --202 + j*(-446) -452 + j*(360) --205 + j*(-263) --283 + j*(320) --358 + j*(266) -170 + j*(28) --288 + j*(-393) -97 + j*(423) -122 + j*(425) --6 + j*(146) -144 + j*(-282) -368 + j*(413) --320 + j*(410) --513 + j*(-503) -237 + j*(-528) --398 + j*(254) --237 + j*(474) --128 + j*(499) -233 + j*(396) -262 + j*(404) -240 + j*(-390) --372 + j*(245) --313 + j*(-37) --99 + j*(-187) --301 + j*(-677) --321 + j*(120) -294 + j*(-131) -276 + j*(-228) --313 + j*(-604) --140 + j*(-262) --437 + j*(-173) -98 + j*(192) -235 + j*(394) -256 + j*(-503) -336 + j*(383) -138 + j*(277) --56 + j*(260) --305 + j*(-528) -206 + j*(59) -221 + j*(191) -552 + j*(-141) -15 + j*(434) -223 + j*(24) -56 + j*(325) --49 + j*(238) --410 + j*(270) -11 + j*(-322) --91 + j*(-492) --315 + j*(-44) --165 + j*(-332) -242 + j*(108) -29 + j*(226) -95 + j*(-47) --218 + j*(-109) -251 + j*(-426) --332 + j*(213) -33 + j*(443) -207 + j*(-475) -148 + j*(-1) --147 + j*(-504) --158 + j*(1) -378 + j*(15) --612 + j*(-174) -255 + j*(182) -240 + j*(-387) --206 + j*(176) -523 + j*(-181) -241 + j*(-255) --362 + j*(-265) -84 + j*(100) --299 + j*(165) -291 + j*(192) --109 + j*(-377) --72 + j*(532) --86 + j*(-276) -250 + j*(489) --301 + j*(-421) -187 + j*(401) --241 + j*(58) --369 + j*(-199) -23 + j*(501) --194 + j*(-318) --278 + j*(578) -552 + j*(223) --197 + j*(-253) -231 + j*(-304) --33 + j*(-308) -296 + j*(437) --462 + j*(445) -57 + j*(-146) --127 + j*(94) -98 + j*(21) -392 + j*(-337) --290 + j*(244) --216 + j*(434) -112 + j*(-111) -1 + j*(-450) -294 + j*(115) --486 + j*(-211) --293 + j*(-436) --181 + j*(315) -231 + j*(375) -192 + j*(-240) -200 + j*(-343) --310 + j*(34) --459 + j*(-279) --173 + j*(-120) -391 + j*(-253) --197 + j*(-226) -224 + j*(-334) --604 + j*(325) --18 + j*(-379) -269 + j*(-285) -454 + j*(483) --172 + j*(-185) --479 + j*(135) -319 + j*(275) -423 + j*(-495) --319 + j*(315) -22 + j*(466) --86 + j*(-120) -224 + j*(198) -210 + j*(-262) -106 + j*(170) --293 + j*(220) -491 + j*(524) -128 + j*(525) --318 + j*(419) -352 + j*(-143) --196 + j*(130) --222 + j*(317) -302 + j*(-421) -388 + j*(-199) --243 + j*(395) -87 + j*(397) --383 + j*(296) -99 + j*(-499) --97 + j*(-214) -279 + j*(-408) --428 + j*(-327) -250 + j*(-131) -260 + j*(110) --346 + j*(323) --204 + j*(341) --344 + j*(-276) -266 + j*(-33) --482 + j*(-466) --284 + j*(10) --331 + j*(236) -66 + j*(272) --415 + j*(227) -16 + j*(81) --647 + j*(671) --20 + j*(93) --130 + j*(-244) --272 + j*(74) --243 + j*(379) -168 + j*(-558) --49 + j*(264) --257 + j*(231) --298 + j*(231) -235 + j*(496) -263 + j*(77) --192 + j*(250) -110 + j*(87) --301 + j*(49) -391 + j*(-658) -482 + j*(-317) -267 + j*(-197) -89 + j*(-107) -240 + j*(-375) --354 + j*(-299) --441 + j*(-1) -113 + j*(-134) -530 + j*(-79) -405 + j*(-101) -476 + j*(45) -460 + j*(145) -332 + j*(-77) --86 + j*(-153) -74 + j*(-574) --298 + j*(-58) --220 + j*(-371) -438 + j*(192) --325 + j*(175) --132 + j*(-379) -225 + j*(96) -307 + j*(-55) --137 + j*(303) --112 + j*(423) --327 + j*(-241) --329 + j*(351) -62 + j*(-287) -372 + j*(-214) -426 + j*(-216) -176 + j*(-170) --449 + j*(-296) -522 + j*(-1) --66 + j*(396) --223 + j*(92) -228 + j*(165) --233 + j*(105) --272 + j*(-164) -248 + j*(121) --518 + j*(20) --65 + j*(-497) --272 + j*(118) -166 + j*(-117) --279 + j*(-284) -426 + j*(-590) --317 + j*(346) -197 + j*(421) -552 + j*(181) --163 + j*(290) -253 + j*(-554) -60 + j*(16) --336 + j*(-438) --154 + j*(-322) --202 + j*(188) --177 + j*(-8) --427 + j*(-361) --353 + j*(27) -406 + j*(119) --326 + j*(-155) -170 + j*(-190) --235 + j*(59) --67 + j*(287) -106 + j*(438) -192 + j*(-505) -173 + j*(-77) --147 + j*(-275) --683 + j*(342) --411 + j*(433) -307 + j*(4) --506 + j*(44) -322 + j*(-171) -337 + j*(-151) -276 + j*(332) --269 + j*(293) --8 + j*(151) --552 + j*(216) --168 + j*(-276) -195 + j*(-460) -287 + j*(645) --132 + j*(-112) -681 + j*(355) -336 + j*(-137) --539 + j*(-412) -82 + j*(433) --363 + j*(-254) --175 + j*(311) --180 + j*(155) -759 + j*(222) --756 + j*(387) -598 + j*(11) --66 + j*(47) -354 + j*(-71) --262 + j*(-247) --397 + j*(14) -400 + j*(-116) -141 + j*(132) -387 + j*(38) -269 + j*(-296) -457 + j*(54) --173 + j*(85) --370 + j*(191) -53 + j*(-285) --457 + j*(-389) -60 + j*(-470) -384 + j*(-293) --405 + j*(139) --138 + j*(168) --107 + j*(-69) -334 + j*(-50) -210 + j*(-148) -268 + j*(-327) --325 + j*(316) --157 + j*(3) --202 + j*(-96) --214 + j*(244) --336 + j*(-150) -495 + j*(-384) -380 + j*(283) --184 + j*(-419) -293 + j*(339) -178 + j*(67) --156 + j*(249) --563 + j*(407) --561 + j*(185) --93 + j*(-275) --299 + j*(363) -356 + j*(482) -301 + j*(163) --518 + j*(-438) --379 + j*(-109) --474 + j*(438) -486 + j*(180) -204 + j*(648) --122 + j*(190) --387 + j*(-214) -10 + j*(238) -124 + j*(406) -420 + j*(-313) --163 + j*(110) --330 + j*(-315) -303 + j*(262) -371 + j*(189) -452 + j*(-500) -430 + j*(-48) --10 + j*(129) --278 + j*(136) --366 + j*(420) -163 + j*(-250) -337 + j*(-217) -326 + j*(473) --353 + j*(-308) --11 + j*(-25) -106 + j*(-86) -237 + j*(325) -368 + j*(340) -53 + j*(-92) -116 + j*(-206) -163 + j*(206) --122 + j*(185) -282 + j*(-407) --41 + j*(35) --279 + j*(110) --204 + j*(4) -42 + j*(236) --190 + j*(66) -2 + j*(-25) --112 + j*(-47) -35 + j*(-76) -165 + j*(293) --218 + j*(-17) --69 + j*(-71) --158 + j*(48) -88 + j*(-57) --67 + j*(-9) --144 + j*(-40) --216 + j*(218) --161 + j*(88) -100 + j*(89) -226 + j*(219) --10 + j*(0) -96 + j*(-326) -79 + j*(-63) --82 + j*(219) -345 + j*(69) -486 + j*(-264) --37 + j*(11) -373 + j*(-105) --292 + j*(-99) -214 + j*(-145) --187 + j*(-156) --96 + j*(-194) --200 + j*(-57) --134 + j*(-142) -152 + j*(-251) --112 + j*(25) --33 + j*(179) --177 + j*(-7) --245 + j*(1) --114 + j*(122) --9 + j*(-83) --157 + j*(132) --173 + j*(-385) --25 + j*(308) -280 + j*(-180) --240 + j*(-129) --286 + j*(-115) --184 + j*(161) -180 + j*(-82) --2 + j*(383) --139 + j*(192) -112 + j*(-71) -178 + j*(-163) -104 + j*(15) --103 + j*(-185) --207 + j*(197) --78 + j*(108) -86 + j*(60) -52 + j*(296) --240 + j*(-98) --9 + j*(150) -107 + j*(-222) -281 + j*(223) --79 + j*(-42) -49 + j*(-105) --157 + j*(84) -42 + j*(-150) -80 + j*(-23) -178 + j*(-237) -269 + j*(119) --438 + j*(-72) --51 + j*(-114) --279 + j*(-76) -130 + j*(97) --125 + j*(138) -100 + j*(-168) --332 + j*(155) -112 + j*(413) -175 + j*(-136) --450 + j*(77) -34 + j*(51) --140 + j*(257) -170 + j*(-117) --275 + j*(-221) -30 + j*(361) -0 + j*(35) --165 + j*(-214) -227 + j*(186) -326 + j*(363) -175 + j*(11) --52 + j*(51) -153 + j*(-244) -0 + j*(-8) --78 + j*(68) -25 + j*(-67) -88 + j*(7) --204 + j*(216) -117 + j*(127) --214 + j*(-161) -192 + j*(285) --366 + j*(13) -185 + j*(92) --117 + j*(-243) -132 + j*(0) -141 + j*(9) --138 + j*(-232) --107 + j*(147) -175 + j*(-41) -35 + j*(47) -175 + j*(-52) -109 + j*(-82) --18 + j*(-75) -94 + j*(47) -76 + j*(111) -59 + j*(-148) -137 + j*(168) --24 + j*(171) --44 + j*(262) --299 + j*(-66) -130 + j*(-274) -64 + j*(-99) -10 + j*(-214) --251 + j*(330) --77 + j*(-100) --239 + j*(226) --83 + j*(-61) --240 + j*(162) --475 + j*(173) --32 + j*(-143) -112 + j*(238) --8 + j*(-178) --95 + j*(247) --33 + j*(87) --302 + j*(298) -202 + j*(69) -33 + j*(-87) --184 + j*(-31) -234 + j*(220) -122 + j*(-123) --64 + j*(155) -106 + j*(115) -161 + j*(56) -72 + j*(243) --27 + j*(47) --3 + j*(-138) --302 + j*(-216) -156 + j*(-93) --139 + j*(-104) --316 + j*(45) --161 + j*(345) --354 + j*(110) --79 + j*(155) -193 + j*(21) -31 + j*(-125) --119 + j*(-205) -35 + j*(21) --75 + j*(241) -23 + j*(-146) -224 + j*(-222) --171 + j*(231) --61 + j*(-42) --372 + j*(102) --19 + j*(-151) -368 + j*(89) -318 + j*(-52) --327 + j*(-301) -47 + j*(57) --243 + j*(-231) --461 + j*(59) -118 + j*(-65) -67 + j*(202) -402 + j*(-226) --123 + j*(-42) --127 + j*(325) --24 + j*(-166) -185 + j*(161) -111 + j*(-74) --44 + j*(-95) --290 + j*(137) --125 + j*(-220) -54 + j*(-77) -70 + j*(46) -153 + j*(-112) -17 + j*(170) --185 + j*(77) -193 + j*(140) --388 + j*(150) --381 + j*(-216) --11 + j*(262) --130 + j*(8) -149 + j*(-19) -240 + j*(134) -101 + j*(-161) -147 + j*(-86) -101 + j*(51) -110 + j*(-91) -67 + j*(126) -122 + j*(-72) --100 + j*(-166) -146 + j*(-159) --175 + j*(208) --90 + j*(-16) --288 + j*(-130) --256 + j*(-168) --29 + j*(62) -68 + j*(95) -18 + j*(95) -147 + j*(-91) --11 + j*(162) -136 + j*(35) -98 + j*(33) --180 + j*(308) -171 + j*(-5) --114 + j*(25) --30 + j*(-217) --88 + j*(184) -45 + j*(91) -214 + j*(-21) -91 + j*(348) --92 + j*(-296) --58 + j*(96) -38 + j*(-119) --202 + j*(135) --28 + j*(-60) --123 + j*(31) -102 + j*(12) --132 + j*(217) --28 + j*(245) --267 + j*(5) -41 + j*(249) --21 + j*(-147) -102 + j*(-320) --274 + j*(-25) -156 + j*(-100) -100 + j*(-124) --136 + j*(275) -320 + j*(-35) --115 + j*(104) --11 + j*(-205) --254 + j*(-291) --9 + j*(-318) --97 + j*(195) -279 + j*(29) -269 + j*(227) -67 + j*(-39) --136 + j*(241) --96 + j*(-19) -250 + j*(-127) -84 + j*(-129) -228 + j*(90) --98 + j*(23) --46 + j*(-4) -42 + j*(47) --15 + j*(-37) --122 + j*(-230) -67 + j*(163) -176 + j*(-43) -82 + j*(-132) -115 + j*(157) -86 + j*(33) --325 + j*(-20) --115 + j*(77) --33 + j*(-4) -197 + j*(161) -88 + j*(33) --55 + j*(72) -113 + j*(-60) -135 + j*(132) -9 + j*(291) --468 + j*(99) -122 + j*(-105) -95 + j*(-26) -29 + j*(-37) -40 + j*(-100) --100 + j*(26) --369 + j*(228) -86 + j*(-67) --47 + j*(-98) -52 + j*(-129) -271 + j*(-58) -131 + j*(-315) --78 + j*(361) --2 + j*(-98) -143 + j*(-180) -78 + j*(123) --77 + j*(-190) --92 + j*(-76) -151 + j*(71) --47 + j*(13) -246 + j*(-71) --178 + j*(59) -134 + j*(-88) -243 + j*(-98) --51 + j*(11) -244 + j*(45) --66 + j*(127) -44 + j*(223) -145 + j*(-98) --129 + j*(173) --226 + j*(330) -264 + j*(168) --93 + j*(27) --146 + j*(-133) --203 + j*(-310) -8 + j*(11) -378 + j*(112) -385 + j*(281) -182 + j*(-64) -35 + j*(158) --199 + j*(-1) --168 + j*(120) -192 + j*(-133) --127 + j*(59) --130 + j*(-279) -1 + j*(-224) --70 + j*(-42) -61 + j*(80) --13 + j*(-11) --8 + j*(-95) -132 + j*(-240) --215 + j*(-160) -191 + j*(133) -124 + j*(-373) --161 + j*(-139) -110 + j*(-134) --245 + j*(1) --267 + j*(103) --13 + j*(-384) -226 + j*(-58) -21 + j*(121) --45 + j*(-400) -120 + j*(76) -69 + j*(35) --111 + j*(40) -105 + j*(190) -164 + j*(161) --268 + j*(-40) -177 + j*(-25) --61 + j*(-80) -185 + j*(310) --110 + j*(141) -20 + j*(187) --299 + j*(-25) --24 + j*(326) --92 + j*(-335) -52 + j*(-324) --342 + j*(-267) --91 + j*(-10) -332 + j*(-119) -18 + j*(-219) -54 + j*(140) -333 + j*(237) --201 + j*(207) --99 + j*(294) --49 + j*(-26) -306 + j*(-37) --404 + j*(277) -22 + j*(-156) -348 + j*(-117) -62 + j*(197) -80 + j*(240) --317 + j*(402) -226 + j*(-252) --26 + j*(-31) --107 + j*(65) --45 + j*(7) --237 + j*(-146) --102 + j*(-73) --199 + j*(63) --196 + j*(-39) -68 + j*(50) -111 + j*(-71) -86 + j*(-13) --69 + j*(44) -163 + j*(-116) -181 + j*(-127) --115 + j*(527) -112 + j*(16) --135 + j*(122) -124 + j*(28) -140 + j*(-145) --149 + j*(-218) -51 + j*(-5) -66 + j*(315) -249 + j*(-198) -54 + j*(60) -283 + j*(227) -272 + j*(237) -228 + j*(53) -296 + j*(212) --255 + j*(-52) -252 + j*(93) -49 + j*(-134) -279 + j*(54) --21 + j*(-343) --116 + j*(206) --52 + j*(-47) -69 + j*(187) -21 + j*(93) --28 + j*(-166) --97 + j*(-161) -367 + j*(-90) --39 + j*(53) -400 + j*(92) -381 + j*(-169) --303 + j*(219) -2 + j*(58) -21 + j*(248) --160 + j*(-125) -379 + j*(-387) -62 + j*(-31) --126 + j*(-76) --17 + j*(47) -29 + j*(45) --286 + j*(-181) -21 + j*(103) --117 + j*(29) -86 + j*(386) --132 + j*(-129) -83 + j*(178) -243 + j*(-298) -144 + j*(-295) -111 + j*(-109) --201 + j*(168) -55 + j*(-192) --13 + j*(41) --129 + j*(147) --8 + j*(-37) --39 + j*(32) -28 + j*(90) -323 + j*(-245) -107 + j*(-77) --8 + j*(-421) -187 + j*(-118) --54 + j*(-160) --91 + j*(54) -215 + j*(267) -239 + j*(-159) -106 + j*(-174) --106 + j*(349) --153 + j*(33) -45 + j*(98) --145 + j*(134) --101 + j*(-190) --331 + j*(40) --167 + j*(-255) -129 + j*(-113) -112 + j*(250) -10 + j*(-317) -125 + j*(-106) -96 + j*(102) -238 + j*(-6) --108 + j*(222) --82 + j*(122) --453 + j*(-377) --97 + j*(139) -103 + j*(-56) --425 + j*(28) -164 + j*(154) -152 + j*(-62) -74 + j*(320) -85 + j*(-80) -146 + j*(-23) --291 + j*(-153) --5 + j*(-3) --155 + j*(23) -153 + j*(294) -59 + j*(-132) -5 + j*(153) -59 + j*(-105) -54 + j*(-325) -177 + j*(170) --223 + j*(-124) -183 + j*(-128) -119 + j*(-180) -332 + j*(71) --14 + j*(93) -199 + j*(81) --101 + j*(-75) -7 + j*(-35) --101 + j*(52) -219 + j*(-284) --102 + j*(-143) -16 + j*(-176) -132 + j*(-16) -76 + j*(-266) -24 + j*(-6) --81 + j*(8) --240 + j*(362) --54 + j*(-95) -490 + j*(-91) -201 + j*(-194) --127 + j*(-102) -48 + j*(4) -250 + j*(-54) -146 + j*(-409) -260 + j*(-20) --40 + j*(50) --119 + j*(-64) -319 + j*(-222) --88 + j*(-216) -157 + j*(191) -112 + j*(-34) --222 + j*(-145) --129 + j*(175) -71 + j*(134) -27 + j*(-133) --87 + j*(-340) --175 + j*(126) -76 + j*(54) --261 + j*(172) -64 + j*(-37) --10 + j*(-211) -30 + j*(169) -23 + j*(-247) --204 + j*(-54) -67 + j*(63) -191 + j*(-223) -22 + j*(454) --156 + j*(91) --45 + j*(-122) --23 + j*(-189) --31 + j*(139) -138 + j*(-201) --324 + j*(-299) --88 + j*(158) --8 + j*(-104) -93 + j*(-129) -112 + j*(-8) -75 + j*(-82) -279 + j*(182) -118 + j*(-400) --162 + j*(89) --398 + j*(58) -4 + j*(101) --133 + j*(-206) --42 + j*(-1) --276 + j*(322) --385 + j*(5) -56 + j*(43) -281 + j*(107) --91 + j*(70) -31 + j*(33) -57 + j*(4) -71 + j*(-126) -129 + j*(175) -565 + j*(-270) --211 + j*(40) --54 + j*(216) -57 + j*(-281) -255 + j*(-197) --21 + j*(190) -183 + j*(110) --123 + j*(46) -111 + j*(45) --381 + j*(100) --296 + j*(153) --214 + j*(-46) --221 + j*(-68) -348 + j*(231) -247 + j*(24) --38 + j*(263) --146 + j*(-361) -51 + j*(271) -146 + j*(-119) --86 + j*(-81) --163 + j*(-21) -92 + j*(70) -159 + j*(139) --301 + j*(54) --13 + j*(-272) --105 + j*(25) --95 + j*(-56) -222 + j*(54) -250 + j*(-56) -354 + j*(-152) -139 + j*(59) --126 + j*(-175) -332 + j*(-244) --88 + j*(-8) --214 + j*(-261) --282 + j*(-13) -75 + j*(49) --180 + j*(-13) --69 + j*(66) --161 + j*(-1) -51 + j*(-62) -26 + j*(-37) --54 + j*(323) -264 + j*(-8) --52 + j*(-44) -86 + j*(341) --48 + j*(-54) --469 + j*(167) --436 + j*(-108) --132 + j*(-14) --134 + j*(74) -364 + j*(258) -22 + j*(156) --40 + j*(293) -41 + j*(98) --83 + j*(-12) -117 + j*(59) -89 + j*(216) --9 + j*(146) -40 + j*(-132) -35 + j*(-151) --178 + j*(-33) --194 + j*(-57) --85 + j*(206) --134 + j*(256) -110 + j*(214) -204 + j*(-109) -236 + j*(-13) -113 + j*(-40) --409 + j*(52) --37 + j*(223) -139 + j*(61) --145 + j*(212) --97 + j*(161) -340 + j*(-211) --184 + j*(13) -235 + j*(-4) --237 + j*(-257) -81 + j*(49) -196 + j*(79) -84 + j*(131) -6 + j*(-95) --291 + j*(426) -221 + j*(89) --31 + j*(116) -74 + j*(260) --156 + j*(47) --261 + j*(-265) --8 + j*(-291) -23 + j*(129) -89 + j*(87) -71 + j*(-16) -217 + j*(293) --402 + j*(-98) --1 + j*(4) -84 + j*(-253) -39 + j*(108) -175 + j*(301) --257 + j*(81) --289 + j*(-86) --313 + j*(-76) -39 + j*(-79) -146 + j*(136) -218 + j*(33) --217 + j*(31) --11 + j*(237) --117 + j*(56) -130 + j*(100) -178 + j*(416) -99 + j*(84) -165 + j*(-202) -61 + j*(-320) --215 + j*(186) --78 + j*(220) --235 + j*(-151) --60 + j*(107) --40 + j*(45) --119 + j*(-298) -250 + j*(-164) --129 + j*(-186) -247 + j*(182) -52 + j*(238) --23 + j*(165) -122 + j*(78) -161 + j*(-262) --313 + j*(44) -1 + j*(-35) -1 + j*(-36) -13 + j*(-135) --223 + j*(-115) --320 + j*(303) --268 + j*(-66) --19 + j*(52) --12 + j*(-124) --28 + j*(42) -219 + j*(-94) --272 + j*(-265) --114 + j*(-81) --107 + j*(28) --129 + j*(-131) --139 + j*(-63) -55 + j*(-259) -241 + j*(-81) --159 + j*(43) --125 + j*(221) -119 + j*(-114) -95 + j*(-36) --213 + j*(-377) -109 + j*(-205) -332 + j*(69) -71 + j*(-182) --28 + j*(-100) -95 + j*(-33) -134 + j*(201) --81 + j*(245) --41 + j*(-175) --55 + j*(-212) -235 + j*(-14) -123 + j*(21) --86 + j*(207) --156 + j*(71) --115 + j*(363) -339 + j*(-28) --325 + j*(262) -188 + j*(-102) -112 + j*(189) -19 + j*(-39) -35 + j*(-77) -181 + j*(-13) --77 + j*(-12) -202 + j*(66) --254 + j*(-63) -150 + j*(131) --136 + j*(42) --238 + j*(-233) -467 + j*(-366) --125 + j*(202) --333 + j*(52) --27 + j*(-125) --224 + j*(4) --52 + j*(246) -362 + j*(-105) --151 + j*(-169) -175 + j*(36) --5 + j*(-147) --59 + j*(23) -222 + j*(86) --9 + j*(-178) -95 + j*(-159) --40 + j*(-3) -298 + j*(158) --94 + j*(354) -48 + j*(33) --42 + j*(-237) -120 + j*(115) --9 + j*(-30) -172 + j*(42) -158 + j*(153) --320 + j*(-88) -22 + j*(-382) --199 + j*(-37) -234 + j*(-310) --208 + j*(2) -40 + j*(16) -309 + j*(-85) -123 + j*(-172) -77 + j*(77) --30 + j*(135) --95 + j*(-40) -72 + j*(-25) --43 + j*(37) -237 + j*(-185) --68 + j*(-187) --298 + j*(55) -105 + j*(-116) -82 + j*(81) --107 + j*(-53) -18 + j*(156) --170 + j*(257) --93 + j*(128) -70 + j*(83) --8 + j*(-257) --46 + j*(-182) --496 + j*(-38) --16 + j*(-24) --5 + j*(-170) -152 + j*(-168) --338 + j*(-136) --75 + j*(104) -265 + j*(119) --146 + j*(231) --310 + j*(0) --7 + j*(-157) --48 + j*(-255) -254 + j*(-21) -134 + j*(-4) --101 + j*(146) --236 + j*(-372) --164 + j*(32) -122 + j*(177) --180 + j*(108) -57 + j*(-165) --6 + j*(255) --75 + j*(123) -13 + j*(100) --170 + j*(-28) --135 + j*(173) -83 + j*(151) --379 + j*(16) --8 + j*(44) --325 + j*(57) -186 + j*(129) -46 + j*(-37) --185 + j*(39) -45 + j*(8) --170 + j*(156) -95 + j*(231) -180 + j*(-313) --371 + j*(-122) --106 + j*(112) -23 + j*(303) --59 + j*(-170) -45 + j*(84) -62 + j*(169) --292 + j*(-88) -60 + j*(-78) --204 + j*(-129) --61 + j*(18) --118 + j*(-74) --98 + j*(227) -170 + j*(201) -86 + j*(254) -119 + j*(98) --173 + j*(129) --62 + j*(71) -7 + j*(-236) -216 + j*(161) --129 + j*(-50) --182 + j*(43) --54 + j*(-159) -113 + j*(-342) -107 + j*(-122) --175 + j*(-31) -30 + j*(112) -42 + j*(-136) -123 + j*(-122) -46 + j*(-36) -22 + j*(-10) -124 + j*(356) -297 + j*(-171) --27 + j*(284) -317 + j*(-117) --34 + j*(-349) -177 + j*(16) --259 + j*(112) --161 + j*(-250) --232 + j*(43) --240 + j*(-83) --162 + j*(370) --13 + j*(253) --77 + j*(-49) --6 + j*(-209) --88 + j*(219) --211 + j*(107) -147 + j*(25) --273 + j*(36) --139 + j*(-117) --177 + j*(52) -223 + j*(170) -139 + j*(-26) -168 + j*(-164) -124 + j*(143) -23 + j*(-224) --54 + j*(-113) -243 + j*(-158) --97 + j*(42) --169 + j*(-34) --30 + j*(110) -317 + j*(6) -173 + j*(317) --210 + j*(-268) --126 + j*(11) -56 + j*(-126) -78 + j*(-158) --82 + j*(133) --133 + j*(-240) --180 + j*(-79) --80 + j*(115) --25 + j*(-201) -371 + j*(11) --68 + j*(202) --231 + j*(-102) --69 + j*(-87) --294 + j*(327) --95 + j*(-16) --231 + j*(-69) -53 + j*(240) --58 + j*(84) --94 + j*(90) -141 + j*(176) --90 + j*(-110) --153 + j*(-4) --58 + j*(126) --67 + j*(13) -92 + j*(-43) --13 + j*(-36) --139 + j*(-202) --228 + j*(-331) -180 + j*(34) --257 + j*(458) --211 + j*(111) --337 + j*(83) -40 + j*(-76) -40 + j*(-325) --4 + j*(-22) --124 + j*(2) -112 + j*(-317) -204 + j*(82) --4 + j*(-29) -112 + j*(-193) --70 + j*(-98) --99 + j*(144) -241 + j*(3) --74 + j*(-40) -224 + j*(148) -216 + j*(69) -36 + j*(-23) --28 + j*(-166) -40 + j*(157) -198 + j*(52) --225 + j*(69) -77 + j*(-260) --32 + j*(-78) --313 + j*(-35) -138 + j*(28) --10 + j*(102) -92 + j*(-91) -267 + j*(-384) -148 + j*(211) --44 + j*(170) --30 + j*(207) -125 + j*(51) -175 + j*(-47) --23 + j*(-171) --165 + j*(-109) -176 + j*(83) --62 + j*(148) -124 + j*(-119) --121 + j*(-276) -54 + j*(-243) --163 + j*(-109) -1 + j*(-34) --83 + j*(182) -35 + j*(146) -322 + j*(53) --175 + j*(34) --156 + j*(-173) -83 + j*(428) -195 + j*(-110) -70 + j*(-187) -259 + j*(107) -99 + j*(233) --73 + j*(-90) --73 + j*(52) -48 + j*(327) -108 + j*(-49) -218 + j*(-158) --22 + j*(-165) -296 + j*(-61) --22 + j*(91) --109 + j*(92) -26 + j*(-6) --75 + j*(41) -52 + j*(187) -82 + j*(184) -42 + j*(116) --71 + j*(228) --72 + j*(190) --218 + j*(-179) -156 + j*(284) --151 + j*(0) -191 + j*(-107) --35 + j*(-240) -245 + j*(-145) --96 + j*(-74) -146 + j*(168) --59 + j*(-107) --114 + j*(115) -60 + j*(-71) -93 + j*(5) -46 + j*(142) --16 + j*(63) --232 + j*(151) --312 + j*(-18) -182 + j*(-24) -227 + j*(221) --200 + j*(-145) -251 + j*(254) -25 + j*(-163) --110 + j*(-184) --256 + j*(173) --83 + j*(56) -184 + j*(-23) --12 + j*(-21) --228 + j*(15) -35 + j*(-117) --6 + j*(25) -77 + j*(-12) --243 + j*(-4) -29 + j*(-12) --221 + j*(71) --30 + j*(40) -100 + j*(-631) --146 + j*(-156) -310 + j*(94) -33 + j*(76) --184 + j*(168) --2 + j*(56) --76 + j*(57) --37 + j*(93) -266 + j*(3) -127 + j*(-191) -284 + j*(-4) -63 + j*(248) -327 + j*(-94) --276 + j*(119) --351 + j*(2) -379 + j*(6) --80 + j*(163) -135 + j*(59) --156 + j*(0) -228 + j*(-18) -566 + j*(-95) -375 + j*(-13) --68 + j*(-289) --250 + j*(-154) -98 + j*(79) --4 + j*(0) --165 + j*(153) --36 + j*(285) -70 + j*(-14) --155 + j*(74) -45 + j*(8) -123 + j*(14) --197 + j*(232) --250 + j*(58) --124 + j*(319) -125 + j*(0) -10 + j*(-142) -137 + j*(-70) --180 + j*(146) -280 + j*(77) --252 + j*(-92) -35 + j*(13) --135 + j*(366) -104 + j*(37) --84 + j*(-117) -11 + j*(-238) -74 + j*(-181) -134 + j*(21) --64 + j*(-122) --344 + j*(-146) -194 + j*(-158) --59 + j*(-111) --286 + j*(-121) --225 + j*(71) --93 + j*(-153) -94 + j*(21) -1 + j*(323) -1 + j*(138) --59 + j*(-13) -5 + j*(-44) --55 + j*(47) --45 + j*(126) --136 + j*(105) --420 + j*(-415) --1 + j*(-133) --259 + j*(-263) --106 + j*(-181) --112 + j*(-18) -18 + j*(318) --173 + j*(162) --166 + j*(7) -11 + j*(-161) -326 + j*(3) -90 + j*(301) --198 + j*(-94) -151 + j*(-48) --272 + j*(103) -97 + j*(15) --125 + j*(52) -378 + j*(-346) -40 + j*(-30) --98 + j*(-186) -207 + j*(339) -42 + j*(-130) --16 + j*(13) --33 + j*(49) -140 + j*(193) --49 + j*(233) --106 + j*(-242) --207 + j*(-18) -177 + j*(-38) --520 + j*(-117) -60 + j*(40) --327 + j*(279) -342 + j*(-58) --39 + j*(-69) --127 + j*(-42) -235 + j*(-59) --267 + j*(46) -71 + j*(130) --88 + j*(45) -282 + j*(-4) -219 + j*(-82) --122 + j*(-25) --76 + j*(169) -284 + j*(124) -4 + j*(-43) -83 + j*(-349) -43 + j*(342) -31 + j*(-173) -345 + j*(250) --18 + j*(177) --81 + j*(155) -355 + j*(156) --93 + j*(-11) -141 + j*(3) --83 + j*(77) -340 + j*(-164) --117 + j*(59) -94 + j*(189) -127 + j*(-243) --284 + j*(-161) --19 + j*(-133) -182 + j*(86) --153 + j*(97) --16 + j*(-69) -197 + j*(-16) --18 + j*(29) -8 + j*(-72) --95 + j*(312) --76 + j*(-127) -93 + j*(-103) --127 + j*(16) -78 + j*(329) --69 + j*(111) -182 + j*(192) -43 + j*(-180) --77 + j*(81) --91 + j*(-274) --136 + j*(57) -29 + j*(-122) -291 + j*(-81) --227 + j*(127) --165 + j*(227) -61 + j*(-100) --80 + j*(-31) --211 + j*(-145) --168 + j*(-113) --40 + j*(68) -259 + j*(121) -111 + j*(-69) -245 + j*(47) -11 + j*(-61) --136 + j*(104) -3 + j*(-161) --105 + j*(-15) -122 + j*(-453) --36 + j*(-18) --148 + j*(243) -78 + j*(-107) -181 + j*(276) -276 + j*(-42) -179 + j*(-117) --103 + j*(397) -250 + j*(-53) --25 + j*(184) -108 + j*(-56) -171 + j*(-1) -217 + j*(178) --149 + j*(-189) --134 + j*(-218) -76 + j*(402) --10 + j*(139) -100 + j*(236) -61 + j*(-177) -27 + j*(9) -151 + j*(38) --110 + j*(-92) -222 + j*(-115) -118 + j*(-158) -94 + j*(118) -494 + j*(197) --16 + j*(-27) --307 + j*(-13) --81 + j*(262) -231 + j*(192) -278 + j*(21) -56 + j*(-35) --328 + j*(316) -130 + j*(32) --37 + j*(209) -306 + j*(51) -113 + j*(114) --228 + j*(-101) --45 + j*(22) --106 + j*(-86) --188 + j*(-74) -124 + j*(57) --70 + j*(-83) --216 + j*(-23) --87 + j*(-109) -97 + j*(-263) -78 + j*(90) --15 + j*(256) --103 + j*(350) -21 + j*(-25) -32 + j*(115) -76 + j*(-270) -190 + j*(-41) -8 + j*(195) -127 + j*(-100) --8 + j*(-132) -253 + j*(-117) --100 + j*(5) --57 + j*(-319) --18 + j*(82) -163 + j*(231) --127 + j*(-271) --74 + j*(-243) -39 + j*(-278) --88 + j*(179) --100 + j*(-33) --373 + j*(-333) --182 + j*(-299) --117 + j*(-78) -34 + j*(-185) --117 + j*(155) --28 + j*(56) --161 + j*(-70) --97 + j*(-310) --30 + j*(13) --254 + j*(33) -119 + j*(8) -333 + j*(46) --383 + j*(27) -83 + j*(188) -73 + j*(-217) -59 + j*(60) --166 + j*(266) --177 + j*(123) --356 + j*(-55) --339 + j*(-30) --143 + j*(49) -105 + j*(-224) --173 + j*(305) --35 + j*(202) --185 + j*(-152) --221 + j*(132) --244 + j*(-58) -104 + j*(276) --182 + j*(21) -117 + j*(-134) -285 + j*(-66) -33 + j*(-86) -91 + j*(-28) -6 + j*(50) -83 + j*(-8) --185 + j*(60) --32 + j*(-94) --179 + j*(9) --323 + j*(136) -15 + j*(-417) -197 + j*(-105) --71 + j*(74) -6 + j*(-117) -184 + j*(407) -123 + j*(-37) -57 + j*(12) --52 + j*(168) --188 + j*(-119) -28 + j*(-129) --78 + j*(-1) --104 + j*(-83) -1 + j*(-223) --468 + j*(42) -157 + j*(52) --144 + j*(-72) -75 + j*(296) -45 + j*(-285) --221 + j*(301) --103 + j*(163) --341 + j*(-457) -105 + j*(23) --23 + j*(-88) --264 + j*(-552) -81 + j*(4) --274 + j*(-131) -214 + j*(-18) -151 + j*(-214) --1 + j*(-205) -103 + j*(-49) -81 + j*(-8) --80 + j*(16) -246 + j*(-183) -136 + j*(-100) -35 + j*(-69) --217 + j*(254) -252 + j*(-156) --47 + j*(-160) --162 + j*(167) --148 + j*(-201) -265 + j*(-240) --141 + j*(-8) -35 + j*(33) --99 + j*(-95) --4 + j*(124) -65 + j*(-206) --175 + j*(279) --1 + j*(114) --52 + j*(71) --103 + j*(47) --164 + j*(-41) -206 + j*(216) --148 + j*(19) --161 + j*(-187) --200 + j*(223) -131 + j*(238) -18 + j*(101) -229 + j*(22) -71 + j*(53) -509 + j*(-293) -139 + j*(161) --322 + j*(180) -119 + j*(196) -12 + j*(103) -10 + j*(-187) -104 + j*(-28) -82 + j*(50) -86 + j*(125) -117 + j*(59) --225 + j*(129) -167 + j*(-177) --125 + j*(-100) --178 + j*(-124) --144 + j*(-262) -457 + j*(-237) --267 + j*(22) -240 + j*(22) -155 + j*(89) --6 + j*(-361) -266 + j*(-358) --180 + j*(110) --73 + j*(69) --42 + j*(93) --257 + j*(-151) -3 + j*(141) -192 + j*(356) -26 + j*(-76) -103 + j*(340) -83 + j*(70) -75 + j*(-245) -206 + j*(340) --144 + j*(360) -344 + j*(76) --74 + j*(325) --7 + j*(208) --238 + j*(-206) -25 + j*(83) -57 + j*(-286) --82 + j*(232) -251 + j*(-76) --218 + j*(-234) --170 + j*(-219) --75 + j*(-252) --112 + j*(259) -24 + j*(31) --226 + j*(59) --67 + j*(-4) --344 + j*(-240) --86 + j*(143) -37 + j*(-59) -54 + j*(-173) --264 + j*(-52) -78 + j*(104) --337 + j*(-103) -115 + j*(-144) -228 + j*(4) -93 + j*(-54) -15 + j*(-245) -118 + j*(-70) --8 + j*(-69) -195 + j*(-202) -110 + j*(172) --214 + j*(-326) --74 + j*(199) -81 + j*(124) -59 + j*(141) -88 + j*(-178) --28 + j*(22) -132 + j*(144) -71 + j*(-90) -101 + j*(-243) --191 + j*(32) --12 + j*(-52) -134 + j*(18) --416 + j*(338) -98 + j*(-92) --122 + j*(-18) --123 + j*(-100) --405 + j*(86) -59 + j*(260) --272 + j*(201) --129 + j*(320) --214 + j*(35) --24 + j*(9) --137 + j*(88) --46 + j*(-113) --99 + j*(105) --4 + j*(51) --59 + j*(-19) -267 + j*(56) -77 + j*(-30) -66 + j*(61) -6 + j*(-23) -0 + j*(198) --4 + j*(-117) --58 + j*(5) --141 + j*(143) --4 + j*(100) --150 + j*(-117) -88 + j*(-301) --90 + j*(-31) -247 + j*(58) --84 + j*(-112) -387 + j*(-145) --50 + j*(-57) --117 + j*(-25) --103 + j*(102) -113 + j*(294) -248 + j*(142) --61 + j*(-134) --152 + j*(129) -106 + j*(-170) --332 + j*(-23) --168 + j*(206) -240 + j*(36) --196 + j*(-146) --400 + j*(67) -40 + j*(-26) -110 + j*(213) --288 + j*(252) -53 + j*(206) -253 + j*(-489) --428 + j*(390) --426 + j*(339) -162 + j*(-463) -278 + j*(159) --35 + j*(426) --375 + j*(323) --243 + j*(186) -230 + j*(325) --340 + j*(-334) --193 + j*(148) --640 + j*(75) --14 + j*(106) --49 + j*(233) -93 + j*(225) --23 + j*(-235) --560 + j*(-476) --494 + j*(412) -302 + j*(424) -122 + j*(255) --317 + j*(320) --47 + j*(-134) --411 + j*(412) --241 + j*(107) --639 + j*(-566) -427 + j*(-136) --165 + j*(-217) -515 + j*(471) --91 + j*(-151) -405 + j*(221) -139 + j*(-260) --82 + j*(151) -228 + j*(514) --165 + j*(231) -425 + j*(-11) --210 + j*(117) --475 + j*(247) --291 + j*(500) -18 + j*(-106) -443 + j*(57) --283 + j*(348) -226 + j*(-305) --211 + j*(-33) -412 + j*(-233) --272 + j*(237) --378 + j*(8) -299 + j*(-136) -182 + j*(-98) --489 + j*(183) -41 + j*(286) --64 + j*(226) -102 + j*(351) -375 + j*(471) --121 + j*(252) -310 + j*(-366) -194 + j*(-442) -67 + j*(-332) -190 + j*(-188) -467 + j*(-81) --313 + j*(-344) --49 + j*(-161) --589 + j*(85) --91 + j*(187) -127 + j*(11) --212 + j*(551) -350 + j*(7) -170 + j*(327) --387 + j*(-363) --190 + j*(-612) -207 + j*(319) --121 + j*(315) --401 + j*(161) --432 + j*(209) --467 + j*(-334) -276 + j*(90) -185 + j*(-222) --506 + j*(490) --455 + j*(-293) --49 + j*(-448) -224 + j*(293) -427 + j*(-559) --267 + j*(-164) --23 + j*(-156) --324 + j*(-267) --215 + j*(-33) -98 + j*(-173) --209 + j*(-255) --197 + j*(431) -238 + j*(367) -47 + j*(-198) --308 + j*(-1) --173 + j*(119) --134 + j*(-357) --186 + j*(71) -198 + j*(-59) -66 + j*(298) --412 + j*(45) -416 + j*(426) -127 + j*(231) -285 + j*(-231) -81 + j*(-380) -228 + j*(52) --291 + j*(436) --28 + j*(91) -331 + j*(-356) --12 + j*(800) --144 + j*(303) --334 + j*(206) -316 + j*(250) -272 + j*(-503) --192 + j*(-511) -298 + j*(-80) -23 + j*(-566) -480 + j*(-347) -222 + j*(-330) -148 + j*(256) -505 + j*(-419) -270 + j*(-203) -409 + j*(-450) --115 + j*(325) --101 + j*(-471) --74 + j*(23) --163 + j*(-351) --3 + j*(354) -8 + j*(-183) --196 + j*(132) -329 + j*(-443) -342 + j*(334) --338 + j*(-366) --143 + j*(-636) -464 + j*(-245) --168 + j*(204) -216 + j*(252) -252 + j*(-243) --81 + j*(342) --196 + j*(233) -277 + j*(-301) -367 + j*(-276) -59 + j*(58) -163 + j*(398) --68 + j*(144) -47 + j*(335) -504 + j*(-647) --169 + j*(-404) -343 + j*(-343) --452 + j*(90) --189 + j*(175) --70 + j*(322) -354 + j*(-152) -422 + j*(262) --247 + j*(-209) -569 + j*(157) -75 + j*(-52) --169 + j*(-175) --334 + j*(16) -177 + j*(605) -434 + j*(-502) --339 + j*(37) -57 + j*(-246) -437 + j*(249) --235 + j*(-141) --247 + j*(-356) --54 + j*(-366) --305 + j*(-142) --237 + j*(164) -8 + j*(-373) -204 + j*(107) --617 + j*(136) -429 + j*(-337) --337 + j*(-326) -506 + j*(477) -161 + j*(-22) -149 + j*(231) -202 + j*(-274) --176 + j*(-391) --252 + j*(-400) --28 + j*(167) -256 + j*(-452) -419 + j*(188) --142 + j*(-805) -417 + j*(-392) -10 + j*(197) --335 + j*(105) --114 + j*(149) --170 + j*(265) --387 + j*(-233) --444 + j*(-151) -119 + j*(451) -270 + j*(422) -591 + j*(-421) --250 + j*(-196) -62 + j*(-338) -266 + j*(28) --476 + j*(69) -71 + j*(-97) --52 + j*(-268) --136 + j*(-214) -223 + j*(633) --518 + j*(220) -595 + j*(184) -160 + j*(124) --304 + j*(-202) -246 + j*(187) -64 + j*(300) -368 + j*(108) -255 + j*(-130) --220 + j*(-389) --424 + j*(41) -508 + j*(16) --334 + j*(-446) --89 + j*(81) --685 + j*(169) -273 + j*(-25) -110 + j*(374) -355 + j*(250) --29 + j*(-200) --298 + j*(-629) --508 + j*(144) -319 + j*(-343) -103 + j*(-57) --59 + j*(373) -282 + j*(-14) --102 + j*(350) -147 + j*(14) --185 + j*(35) --260 + j*(220) --337 + j*(-359) -357 + j*(182) -192 + j*(-279) --293 + j*(-5) -257 + j*(217) -247 + j*(-105) --5 + j*(-358) -252 + j*(-95) -69 + j*(-534) --95 + j*(-283) -147 + j*(-37) -170 + j*(409) -394 + j*(452) --110 + j*(-421) --257 + j*(190) --450 + j*(-209) -77 + j*(-546) -161 + j*(16) -337 + j*(-32) -543 + j*(145) --306 + j*(-438) --64 + j*(159) --234 + j*(-197) --445 + j*(-51) --208 + j*(-62) --275 + j*(228) --445 + j*(-221) -524 + j*(-37) -204 + j*(516) -246 + j*(-404) -624 + j*(-243) --118 + j*(264) -61 + j*(194) --132 + j*(-127) -220 + j*(298) --222 + j*(-282) -167 + j*(-286) -330 + j*(466) -501 + j*(0) -620 + j*(414) -134 + j*(-269) --212 + j*(193) -373 + j*(-335) --107 + j*(40) -342 + j*(-279) --286 + j*(138) -190 + j*(238) --321 + j*(-240) --409 + j*(-247) -371 + j*(505) -247 + j*(272) --223 + j*(-23) -111 + j*(349) --177 + j*(306) -466 + j*(92) --267 + j*(322) -301 + j*(231) -460 + j*(-168) --155 + j*(-254) --320 + j*(-181) -50 + j*(-330) -283 + j*(-357) -163 + j*(-354) -67 + j*(379) --105 + j*(-199) -245 + j*(-296) -387 + j*(371) -56 + j*(57) -453 + j*(279) --324 + j*(33) --327 + j*(-474) --238 + j*(308) --28 + j*(-187) --252 + j*(-229) -165 + j*(194) -509 + j*(434) --337 + j*(518) -3 + j*(-243) -275 + j*(378) -237 + j*(-86) -245 + j*(192) -225 + j*(-257) --325 + j*(-468) --482 + j*(291) --266 + j*(63) --496 + j*(315) -408 + j*(-185) --536 + j*(102) --320 + j*(-224) --404 + j*(16) -302 + j*(246) --263 + j*(19) -308 + j*(-209) -8 + j*(363) --605 + j*(-448) -266 + j*(347) -602 + j*(-82) --276 + j*(-238) -296 + j*(111) -293 + j*(-229) --233 + j*(-84) -186 + j*(-148) -193 + j*(365) -99 + j*(-303) -117 + j*(454) --98 + j*(288) --508 + j*(-424) --370 + j*(650) -324 + j*(375) -415 + j*(-221) --211 + j*(40) -258 + j*(-7) --519 + j*(-225) --303 + j*(112) -247 + j*(-286) -303 + j*(-456) -179 + j*(244) -29 + j*(-155) -321 + j*(458) -144 + j*(226) --195 + j*(-434) --52 + j*(-276) --339 + j*(203) --531 + j*(35) --82 + j*(57) --717 + j*(-362) --407 + j*(227) -257 + j*(343) -140 + j*(-224) -403 + j*(195) --177 + j*(469) -158 + j*(-312) -15 + j*(-269) --363 + j*(262) --36 + j*(-339) -342 + j*(-153) --56 + j*(696) -298 + j*(197) --93 + j*(134) --14 + j*(501) -511 + j*(228) --98 + j*(269) -235 + j*(417) -274 + j*(-367) --327 + j*(228) --27 + j*(148) -404 + j*(-207) -411 + j*(332) -449 + j*(276) -716 + j*(725) -42 + j*(429) --163 + j*(527) -156 + j*(274) --593 + j*(-375) -496 + j*(419) -277 + j*(-330) -513 + j*(-36) -175 + j*(-386) -134 + j*(-376) --95 + j*(-299) --179 + j*(57) -465 + j*(416) -342 + j*(317) -158 + j*(47) --141 + j*(248) --173 + j*(206) --394 + j*(119) -392 + j*(136) --315 + j*(195) -335 + j*(450) -176 + j*(8) -613 + j*(-317) -150 + j*(-186) --403 + j*(-643) -133 + j*(-279) -41 + j*(-164) -276 + j*(-46) -298 + j*(396) --260 + j*(-488) --390 + j*(114) -32 + j*(375) --470 + j*(216) -585 + j*(298) --443 + j*(-373) -251 + j*(306) --372 + j*(318) --371 + j*(408) --92 + j*(-80) --286 + j*(14) --351 + j*(59) --21 + j*(366) --197 + j*(-182) --267 + j*(-47) -177 + j*(-265) --443 + j*(-212) -470 + j*(0) -90 + j*(315) --68 + j*(-222) --506 + j*(-289) --236 + j*(-293) -131 + j*(-98) --257 + j*(174) --37 + j*(-494) --486 + j*(35) -195 + j*(-247) -325 + j*(-836) --73 + j*(-497) --91 + j*(531) -642 + j*(-362) -344 + j*(124) --120 + j*(-199) --50 + j*(-488) -1 + j*(-345) -285 + j*(103) -206 + j*(452) -176 + j*(433) --323 + j*(427) --442 + j*(340) --362 + j*(-361) -417 + j*(-184) --148 + j*(251) --289 + j*(-111) --426 + j*(-202) --597 + j*(-365) -409 + j*(199) -227 + j*(339) --284 + j*(-69) -282 + j*(-156) -40 + j*(473) --271 + j*(-76) --228 + j*(-424) --44 + j*(-64) -28 + j*(371) -494 + j*(-400) --192 + j*(368) -199 + j*(211) --148 + j*(-41) -77 + j*(-412) -13 + j*(139) -350 + j*(-71) -40 + j*(117) --59 + j*(320) -240 + j*(-369) -193 + j*(180) -25 + j*(-484) -416 + j*(-252) -323 + j*(-39) -201 + j*(-394) --221 + j*(351) -375 + j*(-190) -249 + j*(562) -197 + j*(-238) -235 + j*(336) -296 + j*(-149) --493 + j*(-477) -310 + j*(-543) -495 + j*(38) --320 + j*(308) --496 + j*(130) --392 + j*(-78) --478 + j*(103) --346 + j*(-525) --134 + j*(-368) --247 + j*(-150) --472 + j*(-18) --354 + j*(40) -349 + j*(131) --284 + j*(312) -308 + j*(189) -67 + j*(-427) --1 + j*(-159) -362 + j*(-454) -219 + j*(262) --53 + j*(-28) --501 + j*(-225) --359 + j*(547) -369 + j*(315) --344 + j*(-361) --492 + j*(403) -500 + j*(-291) -260 + j*(191) -194 + j*(-170) -324 + j*(280) -595 + j*(120) -185 + j*(123) -222 + j*(670) --309 + j*(219) --237 + j*(-138) -338 + j*(-388) --223 + j*(100) --140 + j*(-430) -685 + j*(115) -339 + j*(-9) --100 + j*(-745) --561 + j*(-101) -360 + j*(446) -191 + j*(-467) --243 + j*(-378) --107 + j*(-345) -21 + j*(620) --223 + j*(-322) -409 + j*(-306) --23 + j*(499) --259 + j*(-576) -493 + j*(658) -180 + j*(118) --378 + j*(198) -378 + j*(-53) --554 + j*(-61) --305 + j*(305) -95 + j*(415) -455 + j*(-305) --275 + j*(-77) -390 + j*(-62) --15 + j*(151) --238 + j*(191) --94 + j*(390) -369 + j*(262) -441 + j*(67) -439 + j*(-121) -315 + j*(66) -282 + j*(216) --193 + j*(-280) --194 + j*(625) --240 + j*(231) --228 + j*(68) -245 + j*(144) --467 + j*(64) -23 + j*(523) -46 + j*(-216) --248 + j*(390) -98 + j*(462) --378 + j*(329) -410 + j*(211) --81 + j*(277) -293 + j*(-16) -204 + j*(-506) --78 + j*(151) --88 + j*(455) -242 + j*(-62) --426 + j*(-105) --320 + j*(221) -84 + j*(-386) -398 + j*(565) -50 + j*(248) --254 + j*(-37) --179 + j*(479) --59 + j*(30) --225 + j*(253) -630 + j*(-185) --76 + j*(-363) -136 + j*(-498) -289 + j*(-79) -315 + j*(-177) -367 + j*(60) --131 + j*(-190) --482 + j*(-127) --68 + j*(220) -204 + j*(16) --175 + j*(45) -421 + j*(180) -231 + j*(-324) -93 + j*(334) --344 + j*(-599) --257 + j*(-276) --134 + j*(-98) -384 + j*(-203) -290 + j*(-177) --82 + j*(-226) --367 + j*(-1) -154 + j*(-307) --155 + j*(576) -216 + j*(279) -229 + j*(196) -35 + j*(138) --52 + j*(-210) -24 + j*(231) -153 + j*(-117) --125 + j*(-174) -23 + j*(-64) --96 + j*(-199) --167 + j*(16) -158 + j*(93) --180 + j*(-331) --42 + j*(-5) -6 + j*(521) --161 + j*(197) --6 + j*(-6) -268 + j*(107) --275 + j*(156) -245 + j*(-13) --52 + j*(-217) --221 + j*(355) -84 + j*(-42) -31 + j*(-204) --117 + j*(523) -211 + j*(268) --86 + j*(104) --181 + j*(-62) --45 + j*(-198) -141 + j*(82) --373 + j*(122) --151 + j*(5) --33 + j*(-191) -69 + j*(21) --124 + j*(30) --153 + j*(-206) --49 + j*(-235) --246 + j*(-214) --224 + j*(-144) --77 + j*(-115) --242 + j*(-233) -56 + j*(127) --137 + j*(-156) --108 + j*(-163) --60 + j*(-140) --91 + j*(73) --85 + j*(-101) --141 + j*(30) --144 + j*(34) -82 + j*(-5) -52 + j*(187) --285 + j*(-59) -62 + j*(271) --29 + j*(-113) --1 + j*(225) -101 + j*(-23) --143 + j*(196) --168 + j*(158) --211 + j*(-158) -71 + j*(-28) --115 + j*(-99) --49 + j*(-183) --58 + j*(8) --187 + j*(303) --6 + j*(-127) -188 + j*(-136) --66 + j*(-156) -134 + j*(-123) --78 + j*(41) --134 + j*(-218) --33 + j*(194) --33 + j*(-91) -15 + j*(326) -187 + j*(336) -9 + j*(21) -143 + j*(-202) -64 + j*(388) --179 + j*(-59) -149 + j*(-228) -62 + j*(255) --161 + j*(-35) --98 + j*(-286) --282 + j*(243) --2 + j*(112) --168 + j*(-325) --197 + j*(180) -182 + j*(-438) --193 + j*(-105) -103 + j*(-26) -168 + j*(135) --91 + j*(266) --94 + j*(-79) -165 + j*(228) -215 + j*(-136) --76 + j*(-318) --177 + j*(-263) --272 + j*(156) -337 + j*(-240) -310 + j*(95) -116 + j*(-1) -243 + j*(-195) -223 + j*(-48) --231 + j*(-1) -16 + j*(21) --153 + j*(66) -16 + j*(176) --52 + j*(136) -144 + j*(-22) -89 + j*(-197) -161 + j*(252) --122 + j*(-67) --258 + j*(127) --168 + j*(-146) --155 + j*(-39) -101 + j*(303) -60 + j*(-25) --305 + j*(67) --253 + j*(-231) -91 + j*(-173) -71 + j*(81) -23 + j*(186) --260 + j*(208) --2 + j*(149) --95 + j*(-175) -21 + j*(204) -402 + j*(-2) --8 + j*(-16) --175 + j*(150) -45 + j*(-235) -200 + j*(260) --375 + j*(-325) -179 + j*(166) -152 + j*(246) -6 + j*(80) -212 + j*(-17) --207 + j*(125) --6 + j*(12) -119 + j*(61) --115 + j*(320) -35 + j*(342) --184 + j*(-132) -62 + j*(-43) --151 + j*(125) -117 + j*(-96) -2 + j*(59) --90 + j*(-66) --18 + j*(239) --175 + j*(-296) -112 + j*(-147) -68 + j*(92) -61 + j*(-134) -8 + j*(-170) -59 + j*(225) -150 + j*(135) --108 + j*(-182) -120 + j*(340) --10 + j*(-316) -54 + j*(4) --40 + j*(29) -7 + j*(58) --280 + j*(143) --206 + j*(197) --183 + j*(181) --90 + j*(177) --115 + j*(26) --42 + j*(168) --34 + j*(-195) -32 + j*(125) -272 + j*(-323) --118 + j*(22) -125 + j*(-72) --164 + j*(296) -260 + j*(37) -133 + j*(228) -30 + j*(-123) -90 + j*(167) -39 + j*(83) -63 + j*(445) -7 + j*(-14) --21 + j*(83) --139 + j*(302) --600 + j*(137) --149 + j*(-34) -305 + j*(-392) -208 + j*(151) -26 + j*(16) -135 + j*(-170) --183 + j*(215) --78 + j*(1) --131 + j*(206) -202 + j*(356) -187 + j*(-204) -147 + j*(-86) -283 + j*(107) -30 + j*(-57) -182 + j*(36) --154 + j*(-84) -24 + j*(36) -124 + j*(52) --237 + j*(114) --218 + j*(39) --40 + j*(-302) --456 + j*(4) -136 + j*(63) --20 + j*(33) -81 + j*(-118) --52 + j*(140) -46 + j*(56) -146 + j*(-45) --85 + j*(-44) -33 + j*(-86) --76 + j*(-269) -143 + j*(91) --121 + j*(23) -12 + j*(93) --57 + j*(-215) -47 + j*(-370) -317 + j*(22) --103 + j*(16) -179 + j*(-135) -57 + j*(0) --30 + j*(88) -131 + j*(-74) -207 + j*(-72) --234 + j*(179) --226 + j*(-16) -226 + j*(161) -143 + j*(108) --95 + j*(-100) --24 + j*(-88) -380 + j*(102) -187 + j*(57) --23 + j*(188) -174 + j*(-252) -93 + j*(498) -194 + j*(196) -72 + j*(-33) --112 + j*(20) --106 + j*(-163) --93 + j*(-49) -98 + j*(100) --79 + j*(-144) --322 + j*(-298) --160 + j*(-301) -144 + j*(-13) -262 + j*(-20) --250 + j*(-38) -59 + j*(-44) --1 + j*(219) -234 + j*(-99) --3 + j*(-152) -160 + j*(-97) -359 + j*(152) --6 + j*(-20) --209 + j*(183) --36 + j*(192) --5 + j*(74) --171 + j*(-285) -11 + j*(49) --6 + j*(103) -18 + j*(147) --27 + j*(161) -4 + j*(-77) -193 + j*(-27) -81 + j*(89) --20 + j*(140) --253 + j*(-40) -246 + j*(104) -83 + j*(87) -160 + j*(-54) -277 + j*(4) -129 + j*(-228) -89 + j*(-37) -222 + j*(-259) -4 + j*(-252) --135 + j*(-66) --7 + j*(228) -190 + j*(133) --67 + j*(-235) -157 + j*(-184) -126 + j*(-25) --321 + j*(46) --291 + j*(-25) --365 + j*(-303) -83 + j*(-93) --286 + j*(77) --1 + j*(-198) --246 + j*(-414) -64 + j*(-129) -142 + j*(105) -188 + j*(-168) --139 + j*(-209) --58 + j*(330) --16 + j*(-140) --33 + j*(157) --77 + j*(-275) --151 + j*(-147) --37 + j*(-271) -206 + j*(254) -419 + j*(39) -156 + j*(-215) --33 + j*(86) -164 + j*(-355) --202 + j*(231) --162 + j*(-66) --112 + j*(-197) --72 + j*(-170) --66 + j*(-123) -70 + j*(245) --182 + j*(-83) -173 + j*(-288) -148 + j*(158) -38 + j*(324) -67 + j*(-69) -18 + j*(-21) -49 + j*(-88) -54 + j*(-108) --49 + j*(200) --228 + j*(-81) --436 + j*(-100) --21 + j*(-150) --58 + j*(-40) -368 + j*(-151) --32 + j*(-195) -30 + j*(-35) -190 + j*(21) -191 + j*(-153) --322 + j*(95) --42 + j*(-115) -103 + j*(-181) --110 + j*(183) -76 + j*(-199) --103 + j*(285) -81 + j*(271) -214 + j*(81) -10 + j*(6) -19 + j*(7) -149 + j*(42) --22 + j*(10) -211 + j*(-118) -126 + j*(-46) -276 + j*(163) -86 + j*(155) --108 + j*(19) --16 + j*(-174) -104 + j*(-542) -70 + j*(125) -168 + j*(128) --215 + j*(305) --2 + j*(35) --87 + j*(150) -50 + j*(-389) -111 + j*(136) --211 + j*(-159) --20 + j*(-172) -240 + j*(-195) -205 + j*(57) --98 + j*(43) -194 + j*(-65) --37 + j*(153) -30 + j*(123) --52 + j*(29) --266 + j*(8) --146 + j*(-105) -158 + j*(15) -69 + j*(-259) -304 + j*(176) -96 + j*(160) --39 + j*(-62) -5 + j*(80) --24 + j*(214) -152 + j*(61) -119 + j*(-291) --44 + j*(168) -48 + j*(431) --17 + j*(66) --4 + j*(264) --88 + j*(33) --160 + j*(-226) --238 + j*(-113) -42 + j*(-112) -75 + j*(30) -130 + j*(-27) -100 + j*(175) -106 + j*(-87) --320 + j*(-256) -122 + j*(-37) --141 + j*(-22) -80 + j*(-106) -301 + j*(-71) -117 + j*(-21) -93 + j*(419) -46 + j*(-291) --59 + j*(-177) --76 + j*(47) --64 + j*(-56) --12 + j*(74) --79 + j*(-18) -214 + j*(-89) -122 + j*(-144) --142 + j*(-150) --199 + j*(-298) -13 + j*(-134) --366 + j*(21) --2 + j*(-26) --30 + j*(139) --328 + j*(-211) --141 + j*(235) -253 + j*(-21) --219 + j*(-209) --71 + j*(-62) -82 + j*(-146) --127 + j*(261) --319 + j*(-255) --121 + j*(86) -585 + j*(32) --54 + j*(-60) -282 + j*(58) --122 + j*(221) -84 + j*(110) --153 + j*(1) -44 + j*(209) -229 + j*(110) -313 + j*(69) -202 + j*(-211) -39 + j*(21) -194 + j*(177) -209 + j*(69) --30 + j*(-167) -127 + j*(38) --177 + j*(11) --41 + j*(86) --15 + j*(243) -78 + j*(11) --79 + j*(-228) --116 + j*(-86) -23 + j*(47) -383 + j*(73) -203 + j*(-68) -111 + j*(140) --63 + j*(68) --82 + j*(-229) --157 + j*(-313) --190 + j*(279) --104 + j*(61) --180 + j*(-204) -265 + j*(-153) --42 + j*(-48) -100 + j*(172) --147 + j*(-308) -267 + j*(54) --112 + j*(272) --264 + j*(-36) -29 + j*(-332) -140 + j*(-86) -400 + j*(-38) --121 + j*(-231) --42 + j*(344) -129 + j*(-81) --111 + j*(226) -3 + j*(150) --37 + j*(18) -0 + j*(-82) -153 + j*(151) -81 + j*(91) --136 + j*(184) -503 + j*(-113) --49 + j*(319) -70 + j*(77) -197 + j*(-66) --62 + j*(149) -254 + j*(-122) -45 + j*(-32) -3 + j*(9) -25 + j*(89) -6 + j*(-45) --22 + j*(161) --40 + j*(83) -103 + j*(23) -110 + j*(278) -8 + j*(-61) --57 + j*(37) --99 + j*(86) --64 + j*(339) --37 + j*(214) --84 + j*(6) -303 + j*(-178) -205 + j*(97) -11 + j*(194) -129 + j*(11) -687 + j*(-100) -187 + j*(-238) -40 + j*(-74) -332 + j*(-25) --94 + j*(165) -64 + j*(246) --291 + j*(-108) --121 + j*(-284) -216 + j*(-104) -159 + j*(23) -75 + j*(-47) -70 + j*(4) --10 + j*(-34) --155 + j*(34) --35 + j*(89) --13 + j*(-134) --99 + j*(40) --463 + j*(-13) --252 + j*(172) --22 + j*(-351) --69 + j*(88) --284 + j*(-21) -13 + j*(-6) --35 + j*(-71) --40 + j*(317) -405 + j*(-60) --358 + j*(104) -56 + j*(-119) --135 + j*(-156) --66 + j*(-23) -168 + j*(59) -148 + j*(-76) --213 + j*(-190) --190 + j*(-27) -103 + j*(392) -52 + j*(110) -211 + j*(-61) --165 + j*(218) -3 + j*(-231) -69 + j*(-161) --263 + j*(54) -98 + j*(-191) -30 + j*(167) -45 + j*(9) --373 + j*(181) -69 + j*(105) --23 + j*(-100) --127 + j*(-9) --64 + j*(287) -202 + j*(290) -115 + j*(-109) --72 + j*(-205) -166 + j*(238) -151 + j*(-25) -186 + j*(290) --108 + j*(33) --163 + j*(-180) -148 + j*(124) -94 + j*(-270) --52 + j*(27) -161 + j*(134) --61 + j*(-25) --23 + j*(-233) -93 + j*(-245) -57 + j*(162) --172 + j*(-354) -133 + j*(129) -339 + j*(107) -12 + j*(65) -6 + j*(-80) --51 + j*(-17) --13 + j*(-37) --18 + j*(-258) --54 + j*(-141) -295 + j*(6) --215 + j*(-192) --109 + j*(-73) -105 + j*(43) --277 + j*(-251) -57 + j*(188) --38 + j*(390) --117 + j*(-390) -107 + j*(233) -131 + j*(98) -366 + j*(-215) --136 + j*(-154) -45 + j*(-112) --10 + j*(-6) -27 + j*(-114) --119 + j*(8) --163 + j*(-4) -78 + j*(261) -221 + j*(-37) --92 + j*(-23) -4 + j*(221) --2 + j*(-153) --76 + j*(-158) -66 + j*(141) --182 + j*(136) --446 + j*(-88) -71 + j*(-145) --75 + j*(-87) -101 + j*(-97) --177 + j*(146) -93 + j*(21) -324 + j*(397) -281 + j*(-229) --138 + j*(117) --188 + j*(112) -39 + j*(-66) -163 + j*(-98) -71 + j*(57) --65 + j*(187) -125 + j*(197) --135 + j*(141) --105 + j*(47) -19 + j*(-86) -66 + j*(-235) --480 + j*(225) -76 + j*(28) -342 + j*(47) -0 + j*(-366) --140 + j*(74) -193 + j*(144) --126 + j*(-43) --191 + j*(158) --180 + j*(-55) -63 + j*(-255) --98 + j*(-2) --13 + j*(308) --183 + j*(207) -144 + j*(37) --51 + j*(-175) -28 + j*(-29) --211 + j*(356) --132 + j*(173) --173 + j*(199) -36 + j*(329) --139 + j*(228) --311 + j*(177) -65 + j*(-343) --217 + j*(-20) -119 + j*(18) -29 + j*(-58) -156 + j*(129) --41 + j*(23) -202 + j*(-163) -224 + j*(196) --47 + j*(25) -15 + j*(-122) --182 + j*(280) --170 + j*(21) -8 + j*(-144) -20 + j*(246) --148 + j*(143) -91 + j*(93) -168 + j*(44) --100 + j*(270) --51 + j*(-167) --285 + j*(125) --93 + j*(63) --1 + j*(-290) --214 + j*(-47) --78 + j*(243) --156 + j*(-314) -152 + j*(57) -163 + j*(267) -8 + j*(-167) --262 + j*(114) -132 + j*(49) -199 + j*(-85) -3 + j*(228) -57 + j*(-151) -104 + j*(-98) --45 + j*(-381) -238 + j*(-59) --62 + j*(-158) --96 + j*(-87) -8 + j*(279) --84 + j*(260) -276 + j*(127) --142 + j*(-42) --119 + j*(-185) -67 + j*(134) --20 + j*(129) --47 + j*(-30) --250 + j*(156) -200 + j*(108) --450 + j*(49) --30 + j*(87) -205 + j*(-137) --165 + j*(217) -100 + j*(-165) --52 + j*(-71) --232 + j*(-131) --289 + j*(-36) -310 + j*(-194) --88 + j*(127) -17 + j*(-71) -50 + j*(232) -181 + j*(21) --65 + j*(-333) -158 + j*(-238) -176 + j*(-210) --279 + j*(173) --21 + j*(-192) --363 + j*(-361) -6 + j*(185) --25 + j*(-4) -62 + j*(-21) -33 + j*(-59) -2 + j*(-121) --192 + j*(-84) -32 + j*(204) -23 + j*(57) --186 + j*(341) -1 + j*(-191) --262 + j*(-313) -121 + j*(13) --211 + j*(-185) --470 + j*(23) --221 + j*(94) -50 + j*(25) --277 + j*(53) -174 + j*(29) --26 + j*(-297) --1 + j*(-285) -90 + j*(-249) -50 + j*(214) -72 + j*(-9) --107 + j*(-288) --98 + j*(-368) --146 + j*(-28) --135 + j*(-53) --245 + j*(240) --88 + j*(134) -211 + j*(-91) --175 + j*(42) -117 + j*(212) -179 + j*(-4) --96 + j*(202) --119 + j*(-134) -22 + j*(291) --515 + j*(119) -36 + j*(-319) -190 + j*(-428) -128 + j*(-48) -458 + j*(-10) --104 + j*(-23) --51 + j*(173) -93 + j*(95) --222 + j*(47) --141 + j*(-39) --175 + j*(-116) -35 + j*(-10) -56 + j*(-146) -275 + j*(14) -14 + j*(31) --105 + j*(-30) -105 + j*(64) -21 + j*(-163) --33 + j*(-29) --56 + j*(-397) --235 + j*(-142) --91 + j*(-166) --112 + j*(-132) -342 + j*(116) -76 + j*(-300) --118 + j*(71) --137 + j*(196) -83 + j*(204) -89 + j*(-214) -78 + j*(-142) --82 + j*(-71) --301 + j*(-57) -141 + j*(111) --74 + j*(4) --76 + j*(179) --545 + j*(209) -121 + j*(-37) -303 + j*(121) --182 + j*(47) -83 + j*(-137) -251 + j*(118) -60 + j*(36) -134 + j*(221) -257 + j*(245) -30 + j*(-115) -192 + j*(-68) --280 + j*(-52) --197 + j*(255) --106 + j*(23) --2 + j*(-309) -175 + j*(305) -78 + j*(31) -86 + j*(-110) --37 + j*(-164) --28 + j*(135) -29 + j*(-107) -161 + j*(228) -269 + j*(167) --46 + j*(-32) --175 + j*(-12) -244 + j*(-436) --118 + j*(276) --151 + j*(-311) --127 + j*(91) -27 + j*(182) -71 + j*(-19) -170 + j*(-5) --67 + j*(75) -196 + j*(233) -253 + j*(47) --23 + j*(-124) -10 + j*(-184) --90 + j*(-4) --13 + j*(-43) --248 + j*(-177) --4 + j*(-153) -192 + j*(-52) --232 + j*(-206) -238 + j*(138) --165 + j*(55) --158 + j*(-70) -77 + j*(55) --6 + j*(47) -227 + j*(-101) -7 + j*(281) --52 + j*(156) -137 + j*(-203) -56 + j*(64) -71 + j*(16) --171 + j*(-17) --127 + j*(325) -8 + j*(91) --107 + j*(197) --25 + j*(22) --203 + j*(-243) -120 + j*(57) -205 + j*(-311) -117 + j*(30) --167 + j*(149) -202 + j*(27) --257 + j*(177) --293 + j*(76) --211 + j*(-262) --106 + j*(-71) --43 + j*(-121) --140 + j*(-146) --118 + j*(138) -114 + j*(-126) -114 + j*(35) --208 + j*(59) -177 + j*(34) --18 + j*(-115) -60 + j*(9) --24 + j*(-62) -288 + j*(66) --176 + j*(-223) -94 + j*(69) -334 + j*(-168) -281 + j*(-23) --40 + j*(139) --59 + j*(-4) --45 + j*(-16) -100 + j*(-16) -216 + j*(-39) -30 + j*(-128) --351 + j*(161) -67 + j*(-194) --213 + j*(-55) -102 + j*(-107) -236 + j*(-30) -317 + j*(-180) -66 + j*(-140) --4 + j*(157) --191 + j*(-49) --101 + j*(-248) --21 + j*(-175) --9 + j*(-108) --268 + j*(-51) -158 + j*(168) -11 + j*(117) --4 + j*(78) -77 + j*(186) -72 + j*(-84) --88 + j*(-228) --66 + j*(-83) --272 + j*(-322) --123 + j*(-65) --105 + j*(25) -368 + j*(-404) -0 + j*(-161) -162 + j*(-31) -96 + j*(232) -236 + j*(-275) -40 + j*(-96) -250 + j*(-218) --234 + j*(-142) --10 + j*(63) --264 + j*(210) -40 + j*(-186) --290 + j*(4) -176 + j*(-90) -109 + j*(282) -13 + j*(465) -40 + j*(7) -129 + j*(-70) --30 + j*(7) --151 + j*(71) --240 + j*(152) --238 + j*(-159) -50 + j*(-19) --81 + j*(76) -132 + j*(-339) -7 + j*(190) -68 + j*(-272) --231 + j*(199) --6 + j*(-153) --71 + j*(224) --362 + j*(203) -122 + j*(-11) -125 + j*(-11) -40 + j*(-13) -69 + j*(370) -128 + j*(-18) --73 + j*(77) --194 + j*(-13) -144 + j*(33) -168 + j*(331) --224 + j*(-53) -18 + j*(-140) --47 + j*(232) -20 + j*(-175) -235 + j*(-91) -241 + j*(-113) --290 + j*(-156) --180 + j*(-276) --187 + j*(69) --25 + j*(-264) --29 + j*(-21) --70 + j*(-210) --301 + j*(-95) --34 + j*(-162) --252 + j*(10) -80 + j*(-33) --62 + j*(-161) -14 + j*(29) -83 + j*(170) -154 + j*(-146) -50 + j*(-245) -112 + j*(82) --60 + j*(132) -257 + j*(174) --10 + j*(-168) -147 + j*(-98) --224 + j*(-255) --240 + j*(-171) -155 + j*(-137) --81 + j*(138) --325 + j*(-52) -247 + j*(141) --365 + j*(16) -385 + j*(-28) -165 + j*(-25) --62 + j*(60) --140 + j*(-218) -426 + j*(178) --83 + j*(156) -163 + j*(-32) -263 + j*(13) --159 + j*(45) --7 + j*(-478) --43 + j*(221) -37 + j*(-121) -57 + j*(-92) -4 + j*(207) --91 + j*(-10) --173 + j*(31) -182 + j*(-86) -153 + j*(59) --259 + j*(-192) -185 + j*(-95) -155 + j*(169) -136 + j*(-41) --330 + j*(-250) --178 + j*(-422) -218 + j*(307) -264 + j*(-365) -317 + j*(-4) -424 + j*(-73) --162 + j*(-162) --238 + j*(-79) --28 + j*(270) --309 + j*(224) -230 + j*(42) -168 + j*(66) -243 + j*(-93) --57 + j*(248) --28 + j*(131) --1 + j*(173) --61 + j*(-118) --35 + j*(104) -156 + j*(-25) -20 + j*(182) --57 + j*(-141) --115 + j*(-38) -68 + j*(-209) -97 + j*(-191) -170 + j*(226) -70 + j*(42) --115 + j*(105) --105 + j*(167) --153 + j*(-176) -1 + j*(214) -144 + j*(404) -76 + j*(303) -220 + j*(2) --428 + j*(-21) --53 + j*(49) --35 + j*(262) -29 + j*(-51) -104 + j*(-71) -161 + j*(-219) -57 + j*(-207) --167 + j*(200) --170 + j*(174) --46 + j*(-60) -4 + j*(-160) -117 + j*(50) -390 + j*(21) --37 + j*(16) -3 + j*(-183) --27 + j*(194) -93 + j*(42) --457 + j*(214) -310 + j*(-107) --8 + j*(-76) -282 + j*(183) --30 + j*(56) -201 + j*(322) -421 + j*(227) -230 + j*(-49) -156 + j*(-142) --208 + j*(-272) --81 + j*(-156) --293 + j*(-89) --108 + j*(-82) -225 + j*(73) --69 + j*(91) --227 + j*(-105) -350 + j*(-50) -8 + j*(-212) --149 + j*(234) --61 + j*(139) -134 + j*(-105) -177 + j*(-169) --113 + j*(113) -178 + j*(44) -120 + j*(62) --1 + j*(253) --45 + j*(-24) -240 + j*(-194) -23 + j*(90) -237 + j*(68) --13 + j*(83) --148 + j*(-37) -136 + j*(-278) --175 + j*(334) -160 + j*(-148) -153 + j*(-133) -60 + j*(124) --221 + j*(-114) -96 + j*(116) --43 + j*(30) -38 + j*(-186) --302 + j*(-27) -93 + j*(-78) --64 + j*(274) --75 + j*(-1) -66 + j*(232) -199 + j*(22) --64 + j*(40) --199 + j*(66) -168 + j*(-209) -122 + j*(-142) -305 + j*(71) --11 + j*(-146) --418 + j*(5) -24 + j*(133) -203 + j*(-218) -394 + j*(165) --156 + j*(-112) -93 + j*(-129) --204 + j*(59) -95 + j*(317) --151 + j*(-274) --122 + j*(-175) --115 + j*(-29) --50 + j*(-112) -224 + j*(-140) -47 + j*(-1) --80 + j*(-177) --244 + j*(-238) --102 + j*(45) --117 + j*(-63) -62 + j*(8) --85 + j*(20) --209 + j*(-100) --118 + j*(-187) --158 + j*(57) --174 + j*(-190) --23 + j*(389) --24 + j*(110) --163 + j*(-100) -45 + j*(234) --49 + j*(76) --349 + j*(193) --40 + j*(-93) -162 + j*(120) --119 + j*(-11) --126 + j*(322) -42 + j*(240) -49 + j*(-10) -445 + j*(175) --243 + j*(78) -95 + j*(-86) -237 + j*(66) -148 + j*(-190) --105 + j*(37) -112 + j*(40) --134 + j*(-176) -241 + j*(-241) --398 + j*(185) --57 + j*(36) -323 + j*(36) -206 + j*(-162) --100 + j*(231) --121 + j*(192) -52 + j*(68) -113 + j*(-16) --312 + j*(-42) -185 + j*(-37) --140 + j*(124) -252 + j*(-82) -74 + j*(-66) --182 + j*(-21) --168 + j*(-48) --198 + j*(-36) --100 + j*(-97) -108 + j*(-23) -16 + j*(-69) --303 + j*(-143) --182 + j*(-119) -149 + j*(-485) -279 + j*(110) --151 + j*(-129) -263 + j*(-245) -166 + j*(28) -216 + j*(74) -25 + j*(96) --122 + j*(146) -81 + j*(103) -129 + j*(-6) --167 + j*(-17) --351 + j*(-259) -3 + j*(-125) --163 + j*(68) -279 + j*(91) --49 + j*(-257) -195 + j*(-93) -47 + j*(118) --197 + j*(-392) --125 + j*(-238) -284 + j*(48) -218 + j*(-397) -72 + j*(-14) --46 + j*(223) --140 + j*(-227) -182 + j*(-205) --218 + j*(-226) --57 + j*(-305) --48 + j*(-37) --199 + j*(-303) -16 + j*(-168) -38 + j*(-11) --73 + j*(-53) --142 + j*(-253) --83 + j*(246) -77 + j*(-91) --128 + j*(-83) --315 + j*(-84) --229 + j*(-173) --238 + j*(-5) -118 + j*(-53) --119 + j*(124) -57 + j*(-78) -33 + j*(-105) --52 + j*(-35) --11 + j*(87) --172 + j*(18) --40 + j*(-88) --42 + j*(188) -3 + j*(-257) --205 + j*(97) -244 + j*(337) --30 + j*(35) -52 + j*(-91) --379 + j*(-11) --187 + j*(-46) --99 + j*(-209) --197 + j*(-16) --168 + j*(-129) --429 + j*(34) --54 + j*(-23) --110 + j*(-78) -328 + j*(98) --142 + j*(139) --204 + j*(124) --123 + j*(-131) --110 + j*(-260) -47 + j*(-187) -138 + j*(121) --160 + j*(91) --414 + j*(-91) --73 + j*(169) --91 + j*(-195) --343 + j*(-139) --105 + j*(-62) -127 + j*(308) -43 + j*(147) --381 + j*(40) --107 + j*(197) -264 + j*(-93) --170 + j*(122) -156 + j*(-71) --37 + j*(233) -77 + j*(51) -152 + j*(14) --35 + j*(76) --259 + j*(124) --253 + j*(10) -234 + j*(-71) -562 + j*(-276) -0 + j*(88) -45 + j*(115) --56 + j*(-43) -262 + j*(25) --69 + j*(119) --143 + j*(-172) -176 + j*(-386) --144 + j*(38) --18 + j*(170) -259 + j*(-262) --8 + j*(88) --113 + j*(-90) -139 + j*(74) -141 + j*(-67) -208 + j*(-146) -118 + j*(46) --156 + j*(-5) --69 + j*(-154) --252 + j*(115) -93 + j*(6) -55 + j*(257) -19 + j*(62) -211 + j*(129) --421 + j*(107) -120 + j*(77) --86 + j*(-219) --292 + j*(-37) --13 + j*(-209) --185 + j*(-60) --71 + j*(163) --301 + j*(-11) --138 + j*(188) -110 + j*(6) -310 + j*(356) -101 + j*(-104) --11 + j*(125) -107 + j*(81) -157 + j*(-269) --98 + j*(-77) -427 + j*(-223) --159 + j*(154) -11 + j*(148) --168 + j*(-61) -19 + j*(-80) --69 + j*(276) --376 + j*(283) -23 + j*(91) --237 + j*(41) --194 + j*(11) --209 + j*(-356) --21 + j*(170) --204 + j*(92) -180 + j*(89) --72 + j*(52) --102 + j*(128) -155 + j*(-105) --308 + j*(215) --206 + j*(187) --31 + j*(27) --264 + j*(33) -192 + j*(50) --184 + j*(-98) --213 + j*(-190) --296 + j*(-141) -42 + j*(-74) -59 + j*(153) --2 + j*(-122) -124 + j*(-98) -37 + j*(-61) --5 + j*(-226) --327 + j*(-73) -187 + j*(238) --193 + j*(145) --49 + j*(199) -12 + j*(-103) -254 + j*(-51) -138 + j*(-86) -166 + j*(-317) -61 + j*(-37) --264 + j*(37) --108 + j*(-327) --274 + j*(312) --293 + j*(146) --120 + j*(-36) -153 + j*(-57) -91 + j*(205) --26 + j*(432) --310 + j*(168) -137 + j*(171) --57 + j*(11) -233 + j*(-103) --19 + j*(-187) --33 + j*(-207) --239 + j*(153) -250 + j*(-412) -23 + j*(-238) -218 + j*(-332) -284 + j*(-149) -68 + j*(37) --3 + j*(303) -145 + j*(90) -7 + j*(-6) -93 + j*(-117) -218 + j*(-139) --204 + j*(30) --51 + j*(-193) --52 + j*(-139) --104 + j*(-123) --164 + j*(55) -169 + j*(12) --155 + j*(-104) -230 + j*(26) --1 + j*(93) --243 + j*(-438) --313 + j*(98) -22 + j*(-40) --18 + j*(166) -116 + j*(-16) --221 + j*(156) -10 + j*(-282) --21 + j*(41) --111 + j*(-107) -78 + j*(68) --165 + j*(14) --99 + j*(16) -315 + j*(66) -11 + j*(-98) -65 + j*(97) --82 + j*(227) -35 + j*(-300) --29 + j*(30) -222 + j*(-175) -89 + j*(91) -133 + j*(-55) --165 + j*(26) -294 + j*(-19) --134 + j*(173) --6 + j*(-123) -265 + j*(316) --37 + j*(-37) -37 + j*(-9) --28 + j*(54) -66 + j*(52) --2 + j*(-216) -111 + j*(-18) -144 + j*(153) -46 + j*(17) --18 + j*(184) --277 + j*(-111) -136 + j*(-34) -181 + j*(-19) --358 + j*(42) -112 + j*(24) --58 + j*(-71) -21 + j*(89) -250 + j*(2) --151 + j*(7) --45 + j*(29) --100 + j*(-1) --96 + j*(148) -197 + j*(52) --18 + j*(-540) -7 + j*(-98) --18 + j*(27) -74 + j*(166) --16 + j*(-130) -62 + j*(108) -37 + j*(88) --97 + j*(-153) --11 + j*(36) --204 + j*(48) -70 + j*(115) --161 + j*(142) --72 + j*(-76) -156 + j*(112) -149 + j*(317) --163 + j*(193) -353 + j*(-178) -160 + j*(-74) -67 + j*(201) --218 + j*(146) -111 + j*(42) --27 + j*(28) --207 + j*(-126) -115 + j*(68) -178 + j*(95) -110 + j*(-12) -74 + j*(-181) --38 + j*(-50) -147 + j*(321) -132 + j*(110) -297 + j*(158) --107 + j*(59) -100 + j*(142) --35 + j*(252) -122 + j*(69) -105 + j*(-229) -34 + j*(-2) -479 + j*(-9) --16 + j*(96) -201 + j*(-258) --104 + j*(133) -129 + j*(-23) -194 + j*(134) --106 + j*(-35) --281 + j*(-300) -36 + j*(-212) --175 + j*(21) --287 + j*(86) -79 + j*(-139) -173 + j*(133) -16 + j*(-117) --152 + j*(33) -201 + j*(-59) --149 + j*(150) --75 + j*(-175) --416 + j*(-181) --64 + j*(-284) -0 + j*(401) --170 + j*(425) --214 + j*(-47) --211 + j*(247) --98 + j*(8) --129 + j*(447) -271 + j*(272) -9 + j*(-279) --64 + j*(-25) -176 + j*(240) --462 + j*(-388) --25 + j*(391) -132 + j*(-235) -173 + j*(-240) -371 + j*(-346) -230 + j*(-164) --228 + j*(18) --81 + j*(323) -150 + j*(89) -197 + j*(-226) -387 + j*(-117) -170 + j*(-281) --300 + j*(-19) --4 + j*(-175) -428 + j*(-17) -523 + j*(419) -168 + j*(455) --202 + j*(-57) --372 + j*(-344) --133 + j*(-50) -87 + j*(-18) --21 + j*(347) -237 + j*(446) --267 + j*(-60) --407 + j*(-203) --99 + j*(-204) -259 + j*(247) --342 + j*(342) -273 + j*(330) --400 + j*(238) -365 + j*(-625) -400 + j*(-322) -5 + j*(168) -371 + j*(329) -148 + j*(443) -134 + j*(-100) --497 + j*(272) --395 + j*(400) --403 + j*(267) -411 + j*(-407) --341 + j*(-416) -155 + j*(-460) -332 + j*(-323) --194 + j*(42) --268 + j*(133) -224 + j*(-124) -535 + j*(478) -143 + j*(-390) -368 + j*(-152) --110 + j*(-284) --693 + j*(-241) --386 + j*(450) --215 + j*(373) --156 + j*(189) -349 + j*(-105) -390 + j*(61) -269 + j*(-430) -183 + j*(-207) --150 + j*(-489) -518 + j*(531) -186 + j*(692) -395 + j*(-305) -166 + j*(249) -243 + j*(-417) --135 + j*(-226) -103 + j*(46) -281 + j*(125) -182 + j*(351) --250 + j*(40) --157 + j*(-467) --240 + j*(178) -170 + j*(-20) --379 + j*(-303) --149 + j*(295) -444 + j*(-149) -595 + j*(231) --92 + j*(-199) --362 + j*(-141) --561 + j*(33) -588 + j*(-375) --267 + j*(-479) -327 + j*(100) --598 + j*(-174) --42 + j*(406) -342 + j*(-147) -336 + j*(-131) -140 + j*(115) -438 + j*(119) --50 + j*(100) -277 + j*(402) --230 + j*(-449) -202 + j*(367) -388 + j*(-771) -288 + j*(-619) -204 + j*(-395) --47 + j*(-322) --293 + j*(322) --315 + j*(-171) --141 + j*(127) --414 + j*(-54) -36 + j*(366) --325 + j*(466) -471 + j*(-397) --284 + j*(-148) --380 + j*(111) -277 + j*(-126) -252 + j*(220) -81 + j*(-233) -241 + j*(-114) --260 + j*(417) -462 + j*(-177) --95 + j*(398) --182 + j*(-351) --76 + j*(-392) --268 + j*(-288) -351 + j*(-228) -501 + j*(62) -51 + j*(273) --418 + j*(-262) -385 + j*(198) --156 + j*(497) -185 + j*(-89) --111 + j*(-339) --297 + j*(260) -141 + j*(-395) -202 + j*(-265) -291 + j*(-190) -344 + j*(83) --349 + j*(64) --132 + j*(284) -361 + j*(363) -212 + j*(241) -527 + j*(514) -69 + j*(530) -403 + j*(281) --375 + j*(-121) --355 + j*(-482) -177 + j*(158) -187 + j*(-8) -696 + j*(-346) -132 + j*(-311) -1 + j*(213) -395 + j*(-237) -303 + j*(246) -320 + j*(-262) -308 + j*(187) -527 + j*(18) --641 + j*(192) --265 + j*(-494) -703 + j*(446) -412 + j*(116) --544 + j*(392) -219 + j*(387) --129 + j*(351) --192 + j*(187) --379 + j*(-465) -322 + j*(-293) -192 + j*(-500) -22 + j*(351) --387 + j*(-301) --67 + j*(456) -194 + j*(450) -218 + j*(-581) --276 + j*(-107) -187 + j*(198) -28 + j*(-418) --85 + j*(292) --156 + j*(-344) --214 + j*(-260) --151 + j*(-267) -41 + j*(-289) -347 + j*(329) --33 + j*(-435) -76 + j*(298) -202 + j*(222) --78 + j*(284) -575 + j*(-494) -291 + j*(204) -197 + j*(523) --494 + j*(-342) -86 + j*(328) -257 + j*(600) -236 + j*(-177) --128 + j*(-152) --214 + j*(-280) -251 + j*(352) --202 + j*(17) -74 + j*(424) --280 + j*(276) --160 + j*(293) -337 + j*(310) --448 + j*(-120) --243 + j*(-566) --279 + j*(-2) -298 + j*(483) --263 + j*(459) --253 + j*(-158) --312 + j*(-397) --192 + j*(228) --249 + j*(-423) -51 + j*(-308) -526 + j*(-261) -74 + j*(446) --124 + j*(-276) --95 + j*(444) -16 + j*(163) --301 + j*(110) -457 + j*(-303) --216 + j*(-169) -429 + j*(-260) --603 + j*(436) -57 + j*(324) --115 + j*(-294) -313 + j*(295) -470 + j*(-225) -518 + j*(129) --504 + j*(-204) --540 + j*(-33) --177 + j*(-329) -253 + j*(-247) --467 + j*(-372) -185 + j*(-238) -267 + j*(186) --384 + j*(141) -250 + j*(-291) --3 + j*(-309) --214 + j*(-30) -118 + j*(635) --256 + j*(327) -312 + j*(-137) -197 + j*(-70) -18 + j*(-503) -317 + j*(367) -181 + j*(-424) --344 + j*(-240) -57 + j*(-547) --364 + j*(13) --27 + j*(-107) --59 + j*(80) -369 + j*(51) --217 + j*(-81) --407 + j*(509) -291 + j*(182) --293 + j*(334) -28 + j*(-156) --438 + j*(400) -343 + j*(-96) -477 + j*(371) --287 + j*(-291) -482 + j*(328) --282 + j*(-414) -61 + j*(179) --224 + j*(-69) --153 + j*(331) -188 + j*(-46) -41 + j*(-78) --571 + j*(556) --293 + j*(91) --260 + j*(90) -239 + j*(-81) --174 + j*(-201) -262 + j*(189) --197 + j*(-334) -368 + j*(311) --501 + j*(88) --48 + j*(-481) -325 + j*(389) --238 + j*(86) --356 + j*(-254) --293 + j*(-133) -287 + j*(380) -527 + j*(33) -497 + j*(-288) -432 + j*(-242) -409 + j*(-207) -28 + j*(-156) --240 + j*(181) --320 + j*(-711) --104 + j*(-373) -341 + j*(-32) --406 + j*(-363) -155 + j*(57) --262 + j*(190) -210 + j*(742) -65 + j*(-220) --291 + j*(-206) --197 + j*(352) --100 + j*(-406) -356 + j*(320) --412 + j*(217) --3 + j*(602) -382 + j*(-284) --122 + j*(93) --682 + j*(-298) -276 + j*(62) --551 + j*(75) -607 + j*(474) -26 + j*(235) -252 + j*(-453) --262 + j*(-438) --40 + j*(-168) --53 + j*(71) -192 + j*(431) -435 + j*(-244) -380 + j*(358) --403 + j*(-416) --105 + j*(-338) -58 + j*(-154) --199 + j*(-422) --193 + j*(391) -281 + j*(-103) -298 + j*(-147) -426 + j*(-414) -398 + j*(100) -165 + j*(140) -126 + j*(-89) -122 + j*(300) --155 + j*(-434) --440 + j*(69) -391 + j*(-152) --307 + j*(-64) -285 + j*(-441) --154 + j*(-491) --419 + j*(-529) --31 + j*(-330) -60 + j*(81) --173 + j*(132) -488 + j*(338) --42 + j*(-450) --159 + j*(-192) --74 + j*(-560) -235 + j*(-305) --415 + j*(-184) --165 + j*(-223) -158 + j*(383) -27 + j*(-197) --255 + j*(-47) -438 + j*(315) -138 + j*(-294) --40 + j*(-127) -337 + j*(-310) -257 + j*(239) -25 + j*(385) --507 + j*(55) --337 + j*(185) -355 + j*(501) --223 + j*(258) -161 + j*(-298) --408 + j*(-71) --342 + j*(351) -256 + j*(-382) --455 + j*(194) --324 + j*(457) --124 + j*(509) --184 + j*(209) -51 + j*(-226) --337 + j*(-282) --38 + j*(-43) -95 + j*(110) -163 + j*(-158) --318 + j*(-346) -160 + j*(321) --257 + j*(310) -305 + j*(-486) -258 + j*(214) --281 + j*(-214) -293 + j*(9) --225 + j*(-240) -207 + j*(-445) --308 + j*(185) --59 + j*(-70) --493 + j*(-380) -655 + j*(-197) --268 + j*(-100) -315 + j*(-30) -382 + j*(-180) -45 + j*(-370) -396 + j*(391) --488 + j*(-400) --333 + j*(-64) --162 + j*(456) --315 + j*(-665) -229 + j*(205) --97 + j*(441) -278 + j*(227) --42 + j*(-278) --182 + j*(413) -286 + j*(69) --286 + j*(530) -86 + j*(326) -196 + j*(257) --218 + j*(161) -444 + j*(-151) --243 + j*(11) --325 + j*(329) -648 + j*(55) -546 + j*(632) --120 + j*(370) -127 + j*(-274) -341 + j*(356) -605 + j*(-571) -129 + j*(441) --491 + j*(-367) -427 + j*(-232) --573 + j*(33) -99 + j*(240) --359 + j*(-138) -229 + j*(165) -309 + j*(119) -242 + j*(284) --192 + j*(27) -621 + j*(-439) --198 + j*(181) --245 + j*(275) --130 + j*(-330) -286 + j*(187) -295 + j*(-190) -665 + j*(218) -266 + j*(-188) --49 + j*(-291) --264 + j*(-29) -156 + j*(-284) -106 + j*(200) -342 + j*(250) -456 + j*(8) --72 + j*(-268) -132 + j*(385) -190 + j*(-104) -125 + j*(-565) -233 + j*(103) -260 + j*(9) -6 + j*(-413) -358 + j*(-296) --222 + j*(-221) --90 + j*(335) -361 + j*(-165) -440 + j*(344) --477 + j*(81) --384 + j*(-272) -366 + j*(144) -482 + j*(268) -368 + j*(-361) -270 + j*(-76) -238 + j*(-549) --412 + j*(-489) --165 + j*(28) --234 + j*(303) -53 + j*(263) --335 + j*(463) -435 + j*(-43) -402 + j*(-403) -573 + j*(438) --498 + j*(-515) --197 + j*(243) -456 + j*(28) --546 + j*(409) --193 + j*(-208) -66 + j*(417) --84 + j*(330) --218 + j*(-150) -378 + j*(202) -177 + j*(-46) -472 + j*(106) --259 + j*(-188) -291 + j*(-82) -251 + j*(423) -187 + j*(-513) -385 + j*(206) --281 + j*(-349) -105 + j*(202) --230 + j*(448) --470 + j*(-348) -13 + j*(-522) --318 + j*(-141) --642 + j*(-298) -82 + j*(-451) --448 + j*(419) -349 + j*(435) --437 + j*(618) --74 + j*(-261) -207 + j*(-99) --386 + j*(292) -290 + j*(-264) -431 + j*(-342) -346 + j*(-221) -240 + j*(151) --209 + j*(-525) --188 + j*(-429) --590 + j*(-514) -409 + j*(-223) --315 + j*(285) --521 + j*(-451) -202 + j*(458) --221 + j*(-139) -236 + j*(378) --672 + j*(421) -1 + j*(315) --83 + j*(-494) --306 + j*(396) -185 + j*(-515) --528 + j*(120) --441 + j*(96) --17 + j*(-30) -213 + j*(271) -631 + j*(-5) -364 + j*(26) -289 + j*(-235) --78 + j*(269) --317 + j*(-59) --365 + j*(-119) --433 + j*(439) -524 + j*(208) --506 + j*(479) -144 + j*(-102) -218 + j*(486) -166 + j*(308) -340 + j*(-202) -195 + j*(376) --243 + j*(18) -666 + j*(-218) --438 + j*(-264) --342 + j*(328) --4 + j*(-325) -266 + j*(344) --282 + j*(80) --177 + j*(581) --470 + j*(-49) -173 + j*(-510) --232 + j*(204) -192 + j*(-291) --95 + j*(-459) --422 + j*(420) --381 + j*(442) --5 + j*(-301) -23 + j*(-64) --246 + j*(-320) -86 + j*(22) -227 + j*(153) -523 + j*(-78) --17 + j*(234) -152 + j*(221) -361 + j*(127) -477 + j*(-136) --260 + j*(-223) --452 + j*(-424) --38 + j*(316) -7 + j*(41) -314 + j*(-93) --199 + j*(-49) -373 + j*(27) -138 + j*(-133) -670 + j*(440) -279 + j*(-281) -651 + j*(-272) --327 + j*(352) --197 + j*(-193) -50 + j*(-195) --464 + j*(169) -91 + j*(299) --268 + j*(-354) --175 + j*(243) -209 + j*(-299) -246 + j*(-74) --211 + j*(32) --590 + j*(-237) --349 + j*(-13) -493 + j*(91) -163 + j*(-473) --229 + j*(-415) -341 + j*(-74) --523 + j*(-462) -233 + j*(354) -476 + j*(-384) --311 + j*(429) --110 + j*(129) -316 + j*(-384) --472 + j*(187) -276 + j*(-151) --118 + j*(-93) -290 + j*(212) -427 + j*(168) --263 + j*(495) -173 + j*(170) --376 + j*(113) --264 + j*(252) --285 + j*(-351) -477 + j*(-281) --305 + j*(39) --271 + j*(75) --76 + j*(113) --59 + j*(45) -64 + j*(-188) -131 + j*(244) -23 + j*(242) -6 + j*(-276) -34 + j*(-119) --132 + j*(123) -158 + j*(-139) --154 + j*(-136) --228 + j*(-295) --5 + j*(-81) --198 + j*(-13) --163 + j*(-329) -123 + j*(-270) --20 + j*(-197) --28 + j*(-51) -145 + j*(-162) -157 + j*(24) --126 + j*(54) -371 + j*(-254) --260 + j*(-204) --182 + j*(-146) -156 + j*(264) -168 + j*(-101) -11 + j*(-81) --284 + j*(-288) --79 + j*(-81) -76 + j*(137) --160 + j*(-287) -165 + j*(-95) -83 + j*(7) -83 + j*(-138) --11 + j*(134) --58 + j*(281) -11 + j*(-214) --231 + j*(-128) -124 + j*(-11) --13 + j*(-123) --122 + j*(154) -286 + j*(-387) --153 + j*(59) --168 + j*(-157) --93 + j*(204) -143 + j*(237) -164 + j*(47) --13 + j*(170) --236 + j*(-96) -57 + j*(395) -71 + j*(-207) --18 + j*(-145) --165 + j*(-25) --185 + j*(-54) -144 + j*(6) --3 + j*(202) --39 + j*(137) -75 + j*(64) -65 + j*(-144) -57 + j*(-88) -130 + j*(-175) -86 + j*(268) --220 + j*(99) --303 + j*(-27) --86 + j*(-230) -0 + j*(-168) --86 + j*(-19) --112 + j*(-159) --46 + j*(-31) --248 + j*(334) -47 + j*(23) -109 + j*(130) --86 + j*(-11) -48 + j*(-79) --115 + j*(35) --107 + j*(139) --181 + j*(244) -33 + j*(-192) -72 + j*(235) -13 + j*(-37) --188 + j*(-218) --122 + j*(139) -83 + j*(211) -11 + j*(-64) --1 + j*(80) -6 + j*(296) --327 + j*(32) -51 + j*(-163) -5 + j*(-147) -89 + j*(-125) -72 + j*(-122) -163 + j*(119) -45 + j*(-27) --14 + j*(194) -67 + j*(35) --115 + j*(138) --69 + j*(352) --124 + j*(264) -358 + j*(-136) -16 + j*(-250) --62 + j*(148) --21 + j*(-112) -100 + j*(-281) --192 + j*(256) --50 + j*(113) -83 + j*(-140) --53 + j*(-184) -26 + j*(226) --146 + j*(-12) -59 + j*(323) -92 + j*(-313) -74 + j*(182) --87 + j*(371) --54 + j*(388) -102 + j*(-137) --317 + j*(235) -113 + j*(-13) --125 + j*(-184) --296 + j*(-134) --24 + j*(-75) -211 + j*(-616) --286 + j*(-27) -153 + j*(129) --287 + j*(221) -139 + j*(-23) -211 + j*(-58) -34 + j*(-3) -68 + j*(58) --232 + j*(52) --57 + j*(-89) -30 + j*(-63) -412 + j*(81) -44 + j*(65) --155 + j*(248) --379 + j*(57) -226 + j*(-62) -40 + j*(-147) -50 + j*(-100) -223 + j*(-29) --38 + j*(-45) --107 + j*(103) --33 + j*(-237) --35 + j*(5) -49 + j*(-75) -230 + j*(-153) -36 + j*(-48) --76 + j*(64) -17 + j*(-260) --31 + j*(134) --52 + j*(-53) --49 + j*(-129) --400 + j*(531) -103 + j*(29) --274 + j*(317) --204 + j*(297) -33 + j*(2) --34 + j*(27) --18 + j*(-21) -118 + j*(49) --165 + j*(-112) -20 + j*(48) -112 + j*(-151) --61 + j*(-64) --165 + j*(-1) --86 + j*(205) --132 + j*(-49) -227 + j*(115) --112 + j*(-151) --229 + j*(208) --18 + j*(288) --11 + j*(-17) --87 + j*(-221) -59 + j*(-103) -178 + j*(34) --68 + j*(78) --331 + j*(236) --50 + j*(202) --406 + j*(300) -168 + j*(360) -66 + j*(135) -210 + j*(-129) -261 + j*(-44) --182 + j*(100) --231 + j*(-123) --11 + j*(49) --225 + j*(-245) -299 + j*(-52) -57 + j*(-13) --121 + j*(342) --224 + j*(191) -13 + j*(-150) --9 + j*(-26) -146 + j*(-146) -192 + j*(-49) --19 + j*(-104) -92 + j*(-254) -214 + j*(-313) --219 + j*(19) --65 + j*(-359) --255 + j*(-38) -65 + j*(177) --96 + j*(-128) --78 + j*(6) -16 + j*(-17) --260 + j*(-66) --95 + j*(-110) -193 + j*(87) -77 + j*(-107) --19 + j*(-52) --70 + j*(-187) -547 + j*(262) --59 + j*(-39) -126 + j*(46) --47 + j*(-180) -18 + j*(-137) -18 + j*(-50) -110 + j*(354) -273 + j*(18) --44 + j*(-349) -97 + j*(-141) -112 + j*(173) -42 + j*(204) --33 + j*(-132) -157 + j*(-131) -62 + j*(-146) -84 + j*(-30) --169 + j*(163) -90 + j*(-85) --211 + j*(215) --147 + j*(-100) --325 + j*(17) -11 + j*(132) --309 + j*(99) --291 + j*(-136) -183 + j*(32) -25 + j*(-317) --243 + j*(-312) -115 + j*(129) --78 + j*(79) -249 + j*(-482) -160 + j*(-260) --12 + j*(130) --395 + j*(1) -330 + j*(-161) -21 + j*(9) --133 + j*(-103) -361 + j*(-362) -222 + j*(204) --265 + j*(88) --35 + j*(197) --187 + j*(123) --22 + j*(101) --37 + j*(12) --42 + j*(-145) -112 + j*(-66) --208 + j*(-199) --221 + j*(181) -2 + j*(-8) --106 + j*(-108) -238 + j*(28) -113 + j*(-265) --43 + j*(-2) --194 + j*(151) -485 + j*(0) --87 + j*(-110) --52 + j*(-28) --11 + j*(144) -63 + j*(-206) -75 + j*(292) --385 + j*(157) --62 + j*(223) --265 + j*(-31) -153 + j*(-35) --298 + j*(-184) -78 + j*(26) --50 + j*(192) -42 + j*(150) -27 + j*(-25) -310 + j*(175) -48 + j*(-118) -100 + j*(55) -120 + j*(175) -327 + j*(-191) -65 + j*(-161) --13 + j*(94) -60 + j*(62) --109 + j*(-181) --36 + j*(-14) --128 + j*(-132) --124 + j*(-5) -88 + j*(-116) -233 + j*(-172) -124 + j*(-318) -93 + j*(-222) --46 + j*(-119) -25 + j*(115) --62 + j*(-232) -182 + j*(-144) -115 + j*(-137) -209 + j*(-123) --194 + j*(156) -141 + j*(-25) -54 + j*(-33) -228 + j*(151) -161 + j*(-208) --235 + j*(-128) -77 + j*(433) --103 + j*(186) --173 + j*(105) --28 + j*(-249) -199 + j*(255) --308 + j*(-40) -72 + j*(-93) --238 + j*(-285) -549 + j*(58) --267 + j*(-106) --11 + j*(-100) -95 + j*(41) -112 + j*(185) -17 + j*(-157) --20 + j*(163) --278 + j*(8) --92 + j*(-59) --197 + j*(37) --441 + j*(-72) --11 + j*(68) -4 + j*(-237) -166 + j*(-2) -15 + j*(-119) --309 + j*(-29) --144 + j*(-14) --230 + j*(-114) --5 + j*(151) --181 + j*(-371) -18 + j*(-228) -163 + j*(-178) -13 + j*(248) --243 + j*(-315) --116 + j*(101) -146 + j*(206) -88 + j*(60) -111 + j*(-144) -0 + j*(281) -10 + j*(-163) --59 + j*(127) -517 + j*(11) -73 + j*(35) -172 + j*(12) -47 + j*(4) --83 + j*(-124) -53 + j*(50) --148 + j*(-124) --141 + j*(238) --54 + j*(41) --139 + j*(-158) --196 + j*(374) --301 + j*(265) --39 + j*(2) -97 + j*(-139) --106 + j*(133) --305 + j*(62) -114 + j*(90) --55 + j*(-114) --122 + j*(-102) -8 + j*(-168) --252 + j*(-70) --70 + j*(42) --141 + j*(-4) --69 + j*(226) -56 + j*(244) -49 + j*(2) --57 + j*(57) --194 + j*(122) --329 + j*(-75) -167 + j*(-91) --197 + j*(279) -117 + j*(-48) -30 + j*(-26) --132 + j*(159) -332 + j*(76) -36 + j*(230) --37 + j*(-238) --40 + j*(-260) -151 + j*(91) --77 + j*(60) -98 + j*(27) -251 + j*(-101) --18 + j*(120) --93 + j*(-235) --76 + j*(8) -404 + j*(191) --8 + j*(-64) -30 + j*(58) --175 + j*(281) --102 + j*(-7) --254 + j*(144) --15 + j*(13) -393 + j*(-165) --185 + j*(-293) --86 + j*(59) --87 + j*(-224) --60 + j*(-87) -177 + j*(-240) -455 + j*(64) -78 + j*(-25) -41 + j*(-100) --71 + j*(-47) -8 + j*(138) -18 + j*(-21) --141 + j*(195) -127 + j*(185) --158 + j*(-86) --62 + j*(5) -206 + j*(103) -156 + j*(-23) -46 + j*(0) -83 + j*(119) --12 + j*(-33) --260 + j*(-20) --59 + j*(-342) -159 + j*(52) -112 + j*(228) -137 + j*(212) --153 + j*(-200) --134 + j*(-71) -262 + j*(312) --369 + j*(-21) -129 + j*(-147) --73 + j*(-161) --117 + j*(110) -110 + j*(113) --8 + j*(49) -52 + j*(296) --158 + j*(-57) --72 + j*(94) --134 + j*(-95) -41 + j*(-303) -177 + j*(-135) --338 + j*(182) --182 + j*(33) --183 + j*(97) -144 + j*(-33) --47 + j*(-262) -139 + j*(95) --286 + j*(88) -318 + j*(-64) -119 + j*(252) --46 + j*(-5) -372 + j*(201) --144 + j*(103) --52 + j*(165) -59 + j*(214) -232 + j*(-100) --237 + j*(85) --396 + j*(-92) --230 + j*(126) --81 + j*(-54) -205 + j*(71) --80 + j*(-67) -322 + j*(-10) --101 + j*(-81) --22 + j*(110) -280 + j*(-179) -26 + j*(-250) -49 + j*(143) --253 + j*(16) --140 + j*(70) -238 + j*(177) -165 + j*(27) --12 + j*(233) -281 + j*(147) -49 + j*(-413) -190 + j*(-138) --115 + j*(280) -184 + j*(-147) -174 + j*(4) --112 + j*(56) --163 + j*(-38) --260 + j*(201) -257 + j*(-362) -344 + j*(141) --185 + j*(-252) -257 + j*(135) --119 + j*(-91) --13 + j*(-37) -133 + j*(21) -72 + j*(58) -71 + j*(368) -276 + j*(279) --87 + j*(293) -46 + j*(-38) --127 + j*(-140) --55 + j*(40) -180 + j*(-16) --54 + j*(267) -59 + j*(213) -24 + j*(-54) --160 + j*(-71) --115 + j*(-206) -0 + j*(-27) -30 + j*(63) -175 + j*(48) -250 + j*(107) -141 + j*(-119) --46 + j*(-228) -141 + j*(55) --11 + j*(-161) -71 + j*(-49) -132 + j*(-453) --171 + j*(134) --240 + j*(-64) --238 + j*(-89) -215 + j*(143) -95 + j*(-177) --115 + j*(12) --98 + j*(-80) -168 + j*(-66) -83 + j*(33) --310 + j*(256) -108 + j*(-310) -206 + j*(83) -103 + j*(61) --42 + j*(-98) -117 + j*(-24) -12 + j*(66) --107 + j*(-325) --97 + j*(-29) -279 + j*(-264) --112 + j*(-161) --330 + j*(88) --315 + j*(-161) --74 + j*(-153) -102 + j*(235) --49 + j*(358) -298 + j*(-292) -170 + j*(292) -139 + j*(254) --199 + j*(-175) -238 + j*(181) --100 + j*(77) --125 + j*(382) -69 + j*(40) --155 + j*(-226) --220 + j*(-99) --39 + j*(-467) --185 + j*(-52) --100 + j*(-15) --55 + j*(84) -80 + j*(278) -52 + j*(-245) --37 + j*(-181) -194 + j*(358) -180 + j*(25) -215 + j*(-21) --254 + j*(128) -208 + j*(43) -148 + j*(-43) -80 + j*(168) -168 + j*(-79) --107 + j*(-41) -98 + j*(250) --51 + j*(-281) -81 + j*(-32) --45 + j*(-207) -95 + j*(31) -29 + j*(60) --104 + j*(-112) -16 + j*(175) -64 + j*(-142) --16 + j*(-264) -90 + j*(-200) -106 + j*(-193) --76 + j*(-26) --81 + j*(226) -4 + j*(-62) --105 + j*(-92) --64 + j*(-13) --118 + j*(-20) --76 + j*(-79) -153 + j*(52) --29 + j*(216) --237 + j*(305) --57 + j*(43) -251 + j*(-64) -65 + j*(-22) --66 + j*(-105) --46 + j*(30) --124 + j*(-200) -186 + j*(108) --303 + j*(98) -127 + j*(-165) -35 + j*(-56) --58 + j*(30) -150 + j*(155) --151 + j*(-247) --194 + j*(-41) --150 + j*(6) --230 + j*(92) --91 + j*(37) -219 + j*(-158) --185 + j*(44) -97 + j*(-40) --209 + j*(43) --160 + j*(44) -111 + j*(-115) --206 + j*(2) --380 + j*(-145) --291 + j*(185) --16 + j*(211) -65 + j*(73) --13 + j*(137) -14 + j*(68) -19 + j*(24) --10 + j*(235) -21 + j*(-56) -36 + j*(-182) --54 + j*(25) -209 + j*(-83) --146 + j*(305) -138 + j*(-47) --152 + j*(-73) -218 + j*(23) -56 + j*(-35) -267 + j*(17) -214 + j*(-84) --240 + j*(309) -98 + j*(45) -211 + j*(-54) -133 + j*(-213) -1 + j*(87) --165 + j*(78) --58 + j*(-218) -10 + j*(-103) --237 + j*(82) --180 + j*(17) --169 + j*(-69) --100 + j*(-223) -339 + j*(34) -288 + j*(-133) --148 + j*(-80) -124 + j*(-6) -278 + j*(115) -88 + j*(39) --99 + j*(-206) -54 + j*(198) --30 + j*(92) --75 + j*(-107) -237 + j*(185) --15 + j*(-160) -141 + j*(182) -129 + j*(169) -72 + j*(9) --214 + j*(236) -133 + j*(21) --25 + j*(74) --122 + j*(-70) --260 + j*(163) --24 + j*(-200) --235 + j*(45) -185 + j*(207) --279 + j*(54) --241 + j*(-18) --153 + j*(-87) --255 + j*(40) --113 + j*(-238) -369 + j*(24) -218 + j*(57) -205 + j*(637) -19 + j*(61) -66 + j*(25) --217 + j*(-431) -62 + j*(208) -269 + j*(-142) -16 + j*(122) -56 + j*(-24) --279 + j*(-170) --141 + j*(233) -339 + j*(-234) --99 + j*(-257) --145 + j*(263) -57 + j*(-175) -36 + j*(250) --94 + j*(-114) --196 + j*(13) -57 + j*(242) -18 + j*(216) --37 + j*(291) -264 + j*(-162) --219 + j*(178) -349 + j*(211) -204 + j*(-43) -21 + j*(93) -21 + j*(-221) -41 + j*(-16) --98 + j*(-230) --264 + j*(-47) -126 + j*(-108) -268 + j*(-69) -41 + j*(65) -76 + j*(301) --84 + j*(-194) --156 + j*(-68) --6 + j*(-103) --9 + j*(-292) --274 + j*(-38) --128 + j*(-166) -57 + j*(127) --155 + j*(-173) --35 + j*(-301) --120 + j*(390) --71 + j*(-32) --16 + j*(-83) --28 + j*(-132) -146 + j*(-89) --233 + j*(134) --136 + j*(-153) --62 + j*(-111) -0 + j*(-173) -240 + j*(314) --331 + j*(-113) -215 + j*(99) --129 + j*(92) -81 + j*(183) -103 + j*(-28) --305 + j*(25) -64 + j*(165) -31 + j*(-141) -503 + j*(144) --18 + j*(-52) --139 + j*(9) --247 + j*(102) --14 + j*(-35) -139 + j*(-177) --218 + j*(1) --123 + j*(-48) --13 + j*(152) -164 + j*(342) --188 + j*(-28) -102 + j*(-18) --275 + j*(-183) --140 + j*(105) --89 + j*(-166) -150 + j*(-127) -153 + j*(202) --160 + j*(98) --30 + j*(-16) -136 + j*(36) -164 + j*(165) --61 + j*(-130) -232 + j*(-411) --65 + j*(129) -184 + j*(-213) --237 + j*(134) --322 + j*(240) --18 + j*(45) -52 + j*(-71) -202 + j*(-8) --103 + j*(-185) --91 + j*(56) --245 + j*(-260) --168 + j*(260) --35 + j*(30) -57 + j*(-226) -57 + j*(49) -199 + j*(-151) -43 + j*(28) --358 + j*(64) --94 + j*(-109) -270 + j*(-82) -132 + j*(7) -206 + j*(10) -506 + j*(-12) --49 + j*(-83) --315 + j*(-318) --15 + j*(277) --157 + j*(-344) -379 + j*(221) -377 + j*(59) -308 + j*(-408) --211 + j*(228) -16 + j*(-142) --260 + j*(-234) --285 + j*(-187) -272 + j*(170) --99 + j*(209) --125 + j*(86) --326 + j*(-369) --164 + j*(-24) --109 + j*(388) --103 + j*(-238) --169 + j*(-40) -10 + j*(-123) -190 + j*(-354) --339 + j*(141) -176 + j*(-11) --105 + j*(4) --83 + j*(-327) --14 + j*(-84) -86 + j*(65) -206 + j*(100) -279 + j*(-349) --328 + j*(191) -21 + j*(-1) -77 + j*(174) -49 + j*(-45) -32 + j*(-206) --141 + j*(75) --64 + j*(33) -174 + j*(88) -328 + j*(-105) -222 + j*(400) --209 + j*(493) --165 + j*(-93) --6 + j*(126) -30 + j*(-97) --117 + j*(-136) --81 + j*(-33) -12 + j*(2) -261 + j*(93) -11 + j*(-62) -10 + j*(98) --125 + j*(-16) -141 + j*(226) -182 + j*(-117) -94 + j*(283) --136 + j*(-20) -455 + j*(-54) --87 + j*(75) --151 + j*(226) --253 + j*(54) --8 + j*(-204) --62 + j*(-136) --182 + j*(148) --16 + j*(74) --17 + j*(-224) --67 + j*(-27) -138 + j*(30) -81 + j*(71) --7 + j*(-83) -127 + j*(98) -22 + j*(-260) -312 + j*(-258) --189 + j*(31) -159 + j*(158) -240 + j*(-91) --32 + j*(-305) -78 + j*(26) -48 + j*(242) --66 + j*(117) -176 + j*(-287) --78 + j*(0) -300 + j*(119) -128 + j*(-288) -22 + j*(161) -373 + j*(192) -272 + j*(70) --50 + j*(84) -3 + j*(54) -26 + j*(86) -49 + j*(182) -46 + j*(-55) --124 + j*(188) --196 + j*(277) -37 + j*(26) --77 + j*(-10) -130 + j*(-244) --35 + j*(421) -9 + j*(219) -177 + j*(49) -48 + j*(-383) --43 + j*(141) --102 + j*(76) -132 + j*(47) --154 + j*(56) --26 + j*(-116) --93 + j*(30) --99 + j*(-182) --301 + j*(-375) -47 + j*(-53) -196 + j*(-124) --271 + j*(-64) --61 + j*(-177) --325 + j*(-323) -8 + j*(147) -32 + j*(67) --158 + j*(-103) -97 + j*(-142) -193 + j*(-113) -168 + j*(-134) -12 + j*(122) --45 + j*(172) -153 + j*(59) -271 + j*(-115) -296 + j*(-90) --117 + j*(-60) --380 + j*(-109) --173 + j*(-264) -25 + j*(-51) -484 + j*(32) --175 + j*(52) --358 + j*(212) -81 + j*(-68) -10 + j*(128) --103 + j*(-35) -44 + j*(351) -202 + j*(36) --97 + j*(279) -87 + j*(103) --70 + j*(27) -133 + j*(235) -109 + j*(199) -146 + j*(88) --90 + j*(-188) --433 + j*(-84) --101 + j*(-179) -202 + j*(-115) -209 + j*(-90) -28 + j*(103) --146 + j*(168) -128 + j*(134) -273 + j*(158) --272 + j*(169) --179 + j*(-197) --387 + j*(-228) --86 + j*(-306) -161 + j*(-260) --61 + j*(-40) --128 + j*(-26) --1 + j*(188) -133 + j*(-36) --50 + j*(41) --20 + j*(-163) -163 + j*(68) -134 + j*(183) --278 + j*(-277) -168 + j*(294) --473 + j*(-18) -25 + j*(364) -61 + j*(-151) -83 + j*(59) -45 + j*(-225) -76 + j*(105) -162 + j*(-346) -101 + j*(94) --37 + j*(-292) --23 + j*(-143) -170 + j*(49) --14 + j*(-16) -22 + j*(71) --111 + j*(-79) -188 + j*(-58) --122 + j*(-239) -252 + j*(161) --45 + j*(-11) -25 + j*(-204) -279 + j*(-64) --137 + j*(-185) --114 + j*(23) -133 + j*(185) -188 + j*(212) --41 + j*(51) -141 + j*(-110) --96 + j*(-378) -58 + j*(-146) -152 + j*(-47) -35 + j*(30) -144 + j*(-59) --202 + j*(64) --265 + j*(-29) -69 + j*(-327) --15 + j*(54) -13 + j*(-119) --33 + j*(273) --203 + j*(81) --108 + j*(275) --109 + j*(119) --165 + j*(-93) --108 + j*(309) --100 + j*(-303) -269 + j*(-175) --293 + j*(95) --129 + j*(183) -187 + j*(-76) -317 + j*(-244) -131 + j*(30) --293 + j*(-280) --96 + j*(170) -11 + j*(219) --88 + j*(-159) --386 + j*(-183) --385 + j*(141) -13 + j*(252) --184 + j*(-351) -473 + j*(213) -6 + j*(-129) -13 + j*(216) -66 + j*(1) -257 + j*(-221) -332 + j*(164) --60 + j*(74) --113 + j*(-6) --59 + j*(264) --11 + j*(37) --74 + j*(263) -80 + j*(-193) --12 + j*(-102) -74 + j*(-3) --25 + j*(-152) -358 + j*(121) -134 + j*(69) --374 + j*(77) -323 + j*(-186) -47 + j*(72) --14 + j*(-469) --23 + j*(-97) --92 + j*(264) -100 + j*(-27) -158 + j*(-268) -32 + j*(55) -291 + j*(-216) --260 + j*(194) -97 + j*(159) --21 + j*(-142) --152 + j*(-19) --64 + j*(358) -162 + j*(18) --225 + j*(90) --127 + j*(234) -64 + j*(43) -141 + j*(45) --250 + j*(9) -52 + j*(-197) -202 + j*(114) --103 + j*(90) -306 + j*(-103) -385 + j*(21) --66 + j*(-288) --187 + j*(-74) --9 + j*(-46) -420 + j*(146) --13 + j*(166) --168 + j*(81) --267 + j*(-56) -98 + j*(-157) --362 + j*(155) -339 + j*(76) -190 + j*(25) --40 + j*(324) --40 + j*(135) --176 + j*(-10) --62 + j*(-112) -42 + j*(201) --52 + j*(-45) -290 + j*(-97) -190 + j*(98) -134 + j*(-165) --162 + j*(-31) --290 + j*(92) --80 + j*(-121) --72 + j*(217) --151 + j*(-44) -42 + j*(140) -185 + j*(-230) -144 + j*(9) -188 + j*(107) --9 + j*(174) -32 + j*(-89) -387 + j*(107) -185 + j*(232) --91 + j*(40) --83 + j*(137) -114 + j*(14) -180 + j*(12) --35 + j*(318) --139 + j*(-17) --3 + j*(-109) -163 + j*(-286) --211 + j*(-83) -29 + j*(21) -401 + j*(-445) --81 + j*(-83) --98 + j*(-218) --121 + j*(-2) -115 + j*(17) -78 + j*(-435) -98 + j*(40) -304 + j*(139) -53 + j*(166) -185 + j*(130) --115 + j*(-383) --170 + j*(-74) --49 + j*(-89) -7 + j*(77) -229 + j*(-230) -91 + j*(-82) -19 + j*(60) --278 + j*(-250) --127 + j*(25) -229 + j*(-180) --57 + j*(36) --25 + j*(163) -84 + j*(-128) -59 + j*(88) --171 + j*(-7) -114 + j*(255) -35 + j*(109) --44 + j*(409) --210 + j*(-250) --69 + j*(66) --121 + j*(48) -125 + j*(-195) -107 + j*(55) --1 + j*(-103) -264 + j*(24) -35 + j*(-345) --250 + j*(-409) -195 + j*(6) --60 + j*(-27) --64 + j*(147) --33 + j*(92) --25 + j*(-93) --228 + j*(-18) --37 + j*(-191) -78 + j*(-4) --69 + j*(-494) --152 + j*(261) --6 + j*(146) --361 + j*(-142) --65 + j*(176) -244 + j*(78) --58 + j*(-261) --58 + j*(-259) --66 + j*(-286) --186 + j*(181) --257 + j*(-41) -194 + j*(354) -47 + j*(93) --121 + j*(31) -136 + j*(-87) -10 + j*(190) --272 + j*(-148) --107 + j*(-56) -115 + j*(-47) --53 + j*(-172) -45 + j*(-48) -347 + j*(-141) -66 + j*(-78) --156 + j*(122) -50 + j*(-180) -217 + j*(-42) --210 + j*(-83) -228 + j*(189) -583 + j*(-493) -196 + j*(153) -40 + j*(-85) -105 + j*(8) --49 + j*(-282) -164 + j*(-246) --35 + j*(-301) -129 + j*(252) --268 + j*(125) --144 + j*(116) --309 + j*(112) -40 + j*(-140) -42 + j*(-145) -39 + j*(161) --340 + j*(243) --55 + j*(-122) -167 + j*(135) --185 + j*(122) -66 + j*(-51) -200 + j*(46) -67 + j*(-173) --50 + j*(126) -536 + j*(-277) -66 + j*(-58) --182 + j*(208) --59 + j*(-201) -253 + j*(46) --20 + j*(-202) -66 + j*(269) -395 + j*(128) --171 + j*(263) --45 + j*(-102) --135 + j*(13) --194 + j*(109) --115 + j*(313) -21 + j*(310) --22 + j*(-176) --59 + j*(-142) -274 + j*(33) -50 + j*(-194) --39 + j*(210) --163 + j*(-13) --247 + j*(316) -163 + j*(-173) -54 + j*(-386) -49 + j*(293) --6 + j*(286) --254 + j*(-59) --308 + j*(-129) -141 + j*(-104) --262 + j*(-76) --92 + j*(346) -318 + j*(-88) -134 + j*(248) --27 + j*(-118) -119 + j*(145) --185 + j*(-234) --141 + j*(-91) --95 + j*(-129) -151 + j*(-233) --91 + j*(-215) --105 + j*(-1) --32 + j*(-80) -133 + j*(-57) --52 + j*(-29) --103 + j*(-84) --65 + j*(-89) --83 + j*(38) --42 + j*(-209) --243 + j*(-137) --74 + j*(-73) --167 + j*(33) --197 + j*(-66) -12 + j*(-21) -88 + j*(-200) -129 + j*(108) -335 + j*(71) -54 + j*(-274) --129 + j*(-361) -338 + j*(-28) -35 + j*(-118) --44 + j*(-242) --66 + j*(-45) --290 + j*(-136) --23 + j*(180) -176 + j*(86) -63 + j*(-119) -68 + j*(-148) --366 + j*(-110) -138 + j*(86) --22 + j*(80) -72 + j*(28) --49 + j*(-218) -64 + j*(14) -364 + j*(-48) -221 + j*(-61) -212 + j*(175) --34 + j*(199) --25 + j*(135) -239 + j*(-129) --253 + j*(-223) -103 + j*(148) -100 + j*(199) -331 + j*(103) -256 + j*(-104) -194 + j*(78) -170 + j*(-54) --51 + j*(83) --112 + j*(288) -298 + j*(88) --196 + j*(-251) --5 + j*(33) -104 + j*(-231) --233 + j*(-22) -115 + j*(-112) -15 + j*(7) -147 + j*(-501) -223 + j*(60) --243 + j*(-366) --35 + j*(100) --64 + j*(-82) --236 + j*(-47) -137 + j*(-5) -31 + j*(-117) -401 + j*(436) --192 + j*(-45) -78 + j*(-392) --258 + j*(263) --303 + j*(-162) -119 + j*(169) -211 + j*(58) --53 + j*(117) --28 + j*(-269) -107 + j*(-180) -107 + j*(-92) --80 + j*(22) -356 + j*(127) --168 + j*(91) --199 + j*(-310) --117 + j*(-108) --193 + j*(-369) -60 + j*(156) -62 + j*(77) --21 + j*(-73) --219 + j*(-141) --418 + j*(11) --44 + j*(-158) -297 + j*(-14) -183 + j*(285) --77 + j*(-115) --92 + j*(-203) -302 + j*(-100) -234 + j*(-197) -275 + j*(88) -57 + j*(-214) -52 + j*(-255) -164 + j*(214) -119 + j*(-187) -117 + j*(86) --3 + j*(340) -95 + j*(-66) -32 + j*(-25) --200 + j*(105) --76 + j*(126) -91 + j*(37) --245 + j*(-36) --120 + j*(77) -120 + j*(-119) --99 + j*(-166) --4 + j*(137) -41 + j*(151) --182 + j*(35) --151 + j*(-89) --63 + j*(-212) -269 + j*(164) -284 + j*(163) -123 + j*(87) --55 + j*(-116) -68 + j*(-134) --62 + j*(-74) -57 + j*(100) -204 + j*(159) -255 + j*(182) -40 + j*(-157) --81 + j*(118) --11 + j*(-113) -168 + j*(-326) -158 + j*(8) --139 + j*(-2) -103 + j*(-64) -54 + j*(606) -202 + j*(32) --240 + j*(-212) --236 + j*(-55) -25 + j*(-208) -124 + j*(-163) -127 + j*(-118) --194 + j*(50) -23 + j*(106) -178 + j*(-280) -92 + j*(-33) --42 + j*(126) -208 + j*(159) --103 + j*(-33) -247 + j*(70) --337 + j*(253) --83 + j*(-166) --199 + j*(12) --92 + j*(542) -178 + j*(-195) --115 + j*(-338) -146 + j*(82) --163 + j*(-86) --88 + j*(-90) -19 + j*(-390) --59 + j*(-48) -81 + j*(165) -103 + j*(-173) -47 + j*(-240) --453 + j*(-52) --102 + j*(234) --272 + j*(161) -81 + j*(-75) --143 + j*(-223) --126 + j*(-250) -134 + j*(-209) -45 + j*(-143) --290 + j*(-23) --88 + j*(14) -382 + j*(-177) --407 + j*(-16) --9 + j*(-69) -401 + j*(-166) -127 + j*(-6) -149 + j*(-99) --124 + j*(-21) -17 + j*(-229) --5 + j*(23) --173 + j*(34) -34 + j*(59) -204 + j*(-1) -48 + j*(253) -247 + j*(154) --158 + j*(172) --81 + j*(340) --23 + j*(-86) --18 + j*(26) -6 + j*(-112) --252 + j*(-152) -186 + j*(148) --199 + j*(76) -330 + j*(6) -13 + j*(-215) --279 + j*(-163) -52 + j*(-40) --167 + j*(-231) --236 + j*(129) -78 + j*(-25) -147 + j*(-44) -119 + j*(125) --149 + j*(-324) -1 + j*(-77) --201 + j*(-49) -250 + j*(-146) -15 + j*(-36) -56 + j*(-78) --35 + j*(-8) --110 + j*(14) -170 + j*(-251) --460 + j*(-7) --32 + j*(-224) --18 + j*(86) --17 + j*(-165) -417 + j*(-276) --87 + j*(72) --205 + j*(-112) -0 + j*(-154) --8 + j*(-245) -147 + j*(27) -89 + j*(-115) --16 + j*(-88) --187 + j*(-146) --93 + j*(8) --11 + j*(181) --159 + j*(4) --132 + j*(92) --23 + j*(-123) -223 + j*(69) --5 + j*(249) --127 + j*(291) -95 + j*(4) -59 + j*(228) -75 + j*(-275) --171 + j*(11) --136 + j*(-105) --198 + j*(204) --57 + j*(5) -3 + j*(-324) --538 + j*(-66) -74 + j*(-358) -467 + j*(20) --421 + j*(-13) -46 + j*(-384) --553 + j*(-285) -178 + j*(18) --197 + j*(97) -333 + j*(-331) --301 + j*(-172) -50 + j*(-204) -291 + j*(331) --132 + j*(-193) --199 + j*(382) --44 + j*(-281) -33 + j*(177) -18 + j*(624) -291 + j*(-469) --192 + j*(71) --414 + j*(254) --331 + j*(-499) -281 + j*(-560) --112 + j*(-367) --390 + j*(-414) -274 + j*(-482) -373 + j*(-433) -320 + j*(128) -250 + j*(-570) --4 + j*(364) -345 + j*(329) --415 + j*(450) -384 + j*(-269) --269 + j*(337) --714 + j*(-90) --144 + j*(-327) -92 + j*(-220) --202 + j*(-617) -368 + j*(187) --391 + j*(445) --446 + j*(485) -606 + j*(-561) --156 + j*(266) -346 + j*(262) -44 + j*(288) -6 + j*(132) -199 + j*(107) -517 + j*(165) -59 + j*(218) -371 + j*(-624) -278 + j*(0) --479 + j*(-395) -390 + j*(-21) -233 + j*(52) --342 + j*(371) --434 + j*(473) --187 + j*(-260) --327 + j*(412) --393 + j*(179) --523 + j*(-187) --343 + j*(-66) -295 + j*(193) -132 + j*(-379) -298 + j*(-465) --434 + j*(26) --532 + j*(284) --207 + j*(-152) --286 + j*(412) --233 + j*(-143) -49 + j*(185) -11 + j*(10) --176 + j*(527) -395 + j*(203) --45 + j*(356) -264 + j*(-517) -189 + j*(-214) -325 + j*(-169) --23 + j*(114) --362 + j*(190) --424 + j*(-215) -442 + j*(496) --311 + j*(-489) -347 + j*(19) --66 + j*(-206) --299 + j*(-675) --133 + j*(-135) -369 + j*(312) --94 + j*(467) -222 + j*(-23) -177 + j*(240) --163 + j*(-114) -278 + j*(-13) -168 + j*(523) --314 + j*(127) --484 + j*(119) -298 + j*(522) --288 + j*(-101) --369 + j*(448) -62 + j*(138) -74 + j*(176) --442 + j*(-165) -25 + j*(-23) -540 + j*(622) -92 + j*(82) --477 + j*(187) -134 + j*(-74) -308 + j*(176) -213 + j*(-274) --223 + j*(-270) --400 + j*(393) -544 + j*(-454) -337 + j*(-287) --313 + j*(466) -304 + j*(397) -118 + j*(-298) --496 + j*(358) -58 + j*(-314) --18 + j*(56) --37 + j*(-183) -85 + j*(-219) -470 + j*(-586) --557 + j*(-581) -425 + j*(194) --148 + j*(-387) -111 + j*(66) -433 + j*(412) -330 + j*(-301) -284 + j*(-236) --71 + j*(156) -243 + j*(-194) -323 + j*(692) -49 + j*(547) --98 + j*(232) --141 + j*(-212) -57 + j*(250) -313 + j*(-370) --641 + j*(-368) --259 + j*(-291) --16 + j*(-18) --689 + j*(241) --308 + j*(-279) -392 + j*(-391) -271 + j*(-156) -40 + j*(334) -84 + j*(-208) --247 + j*(123) -122 + j*(-320) -293 + j*(-576) --299 + j*(446) --459 + j*(-285) --474 + j*(-351) -119 + j*(129) --264 + j*(110) --203 + j*(411) -245 + j*(52) -215 + j*(-194) --147 + j*(333) --242 + j*(-580) -255 + j*(140) -107 + j*(-214) -223 + j*(139) --246 + j*(-601) -219 + j*(-79) -232 + j*(-344) -250 + j*(-248) -76 + j*(64) -380 + j*(-157) -125 + j*(325) --306 + j*(257) -317 + j*(199) --364 + j*(435) --135 + j*(-126) -47 + j*(-95) --303 + j*(-332) --411 + j*(416) --205 + j*(-384) -341 + j*(-59) --47 + j*(-214) --64 + j*(-122) -284 + j*(352) --300 + j*(270) -419 + j*(175) -201 + j*(-445) -269 + j*(409) -381 + j*(225) -262 + j*(487) --52 + j*(-374) -33 + j*(-332) --221 + j*(-178) -57 + j*(-252) --325 + j*(325) -218 + j*(546) --151 + j*(0) -262 + j*(-284) -240 + j*(428) -144 + j*(123) -254 + j*(-41) --361 + j*(365) --5 + j*(288) -392 + j*(-202) -316 + j*(238) -296 + j*(165) -16 + j*(468) -36 + j*(290) --267 + j*(-337) -119 + j*(396) --428 + j*(401) --301 + j*(-145) -288 + j*(-189) -506 + j*(-230) --116 + j*(-116) --217 + j*(-225) -171 + j*(-210) -444 + j*(-202) -223 + j*(124) --432 + j*(522) -133 + j*(235) --234 + j*(-372) --84 + j*(-268) --142 + j*(-271) -189 + j*(148) -67 + j*(16) -342 + j*(278) -355 + j*(319) -115 + j*(-101) -631 + j*(-556) -267 + j*(344) --472 + j*(-622) --483 + j*(433) -327 + j*(373) --462 + j*(457) --331 + j*(139) --59 + j*(-136) -276 + j*(-262) --57 + j*(182) --319 + j*(168) --277 + j*(132) -351 + j*(-30) --111 + j*(260) --291 + j*(560) -425 + j*(622) -221 + j*(-26) -121 + j*(54) --103 + j*(271) --273 + j*(-501) -608 + j*(-200) --373 + j*(-40) -103 + j*(-91) -33 + j*(107) --253 + j*(302) -208 + j*(-200) --401 + j*(78) --143 + j*(-327) -354 + j*(-397) --85 + j*(-421) -280 + j*(-222) -320 + j*(-242) -283 + j*(-122) --399 + j*(407) --46 + j*(9) -244 + j*(171) -462 + j*(-53) --617 + j*(-304) --309 + j*(115) -493 + j*(-261) --403 + j*(140) --300 + j*(86) -643 + j*(4) -339 + j*(-296) --363 + j*(-57) --72 + j*(472) -199 + j*(-41) --198 + j*(212) -369 + j*(185) -228 + j*(-564) --215 + j*(-262) --423 + j*(-37) --159 + j*(371) --373 + j*(-308) --371 + j*(241) --204 + j*(-335) -68 + j*(182) --284 + j*(-345) --332 + j*(-184) -418 + j*(255) -3 + j*(-298) -437 + j*(219) -66 + j*(-67) -98 + j*(-235) --384 + j*(288) --322 + j*(271) --377 + j*(-383) -517 + j*(-313) -53 + j*(211) -356 + j*(158) -131 + j*(23) --161 + j*(-13) -284 + j*(-383) -414 + j*(50) -295 + j*(-61) -239 + j*(-342) -289 + j*(-161) -458 + j*(-262) --348 + j*(-588) --573 + j*(215) -266 + j*(463) -344 + j*(-51) -4 + j*(383) -226 + j*(-94) -306 + j*(-347) -206 + j*(11) -347 + j*(151) --305 + j*(337) -433 + j*(302) --28 + j*(527) --534 + j*(-516) -248 + j*(206) -33 + j*(70) --18 + j*(-231) -231 + j*(-226) --456 + j*(-378) -112 + j*(-158) --90 + j*(-523) -52 + j*(-177) --156 + j*(-113) -46 + j*(268) -22 + j*(422) --191 + j*(-325) --315 + j*(-511) --562 + j*(-180) --69 + j*(-325) -591 + j*(288) --554 + j*(337) --305 + j*(358) --340 + j*(-383) --443 + j*(412) -98 + j*(-349) --403 + j*(219) -401 + j*(-107) -209 + j*(-242) --416 + j*(307) -470 + j*(-292) -249 + j*(344) -84 + j*(520) --99 + j*(-9) --381 + j*(240) -52 + j*(-255) --315 + j*(228) -165 + j*(-340) --385 + j*(-367) -378 + j*(11) -486 + j*(-447) -574 + j*(-212) --550 + j*(-66) -296 + j*(443) --421 + j*(-38) --15 + j*(334) -156 + j*(-60) -291 + j*(184) --148 + j*(-100) --99 + j*(294) -214 + j*(76) -349 + j*(-234) -291 + j*(263) --121 + j*(-279) --119 + j*(-69) -187 + j*(204) -340 + j*(-244) --297 + j*(244) --8 + j*(-47) --105 + j*(-7) --196 + j*(-63) --105 + j*(35) -405 + j*(69) -423 + j*(219) --462 + j*(-112) --197 + j*(-422) -224 + j*(81) --612 + j*(71) -363 + j*(209) -133 + j*(-302) -235 + j*(418) --315 + j*(479) --166 + j*(-6) --97 + j*(140) -278 + j*(451) --301 + j*(212) --412 + j*(-291) -446 + j*(224) -108 + j*(-417) -487 + j*(269) --527 + j*(156) --550 + j*(-249) -543 + j*(424) --126 + j*(57) --230 + j*(-80) --40 + j*(-153) --22 + j*(-342) --75 + j*(-334) -339 + j*(-45) --105 + j*(36) -151 + j*(81) --457 + j*(499) -207 + j*(-512) --276 + j*(462) --246 + j*(-299) --155 + j*(-314) --18 + j*(-281) -233 + j*(-358) -564 + j*(-344) --448 + j*(-518) -477 + j*(84) --371 + j*(-276) -453 + j*(187) --252 + j*(-148) -459 + j*(370) --31 + j*(-509) --215 + j*(-175) --177 + j*(-291) --182 + j*(-204) -298 + j*(47) -200 + j*(-255) --353 + j*(-530) -182 + j*(-202) --296 + j*(-480) -370 + j*(-175) --250 + j*(-131) --74 + j*(-313) --115 + j*(-626) -326 + j*(274) --16 + j*(-218) --151 + j*(-180) --474 + j*(374) -378 + j*(-107) -141 + j*(245) -113 + j*(-241) --526 + j*(1) --300 + j*(-199) -550 + j*(-174) -392 + j*(166) -110 + j*(-38) -301 + j*(-351) -284 + j*(-59) -223 + j*(-526) --282 + j*(608) -317 + j*(332) --503 + j*(-453) --366 + j*(518) -349 + j*(1) -310 + j*(279) --163 + j*(-223) --21 + j*(-283) -443 + j*(-171) -262 + j*(-201) -317 + j*(441) -75 + j*(-129) --223 + j*(223) -296 + j*(91) --455 + j*(-91) --651 + j*(175) -359 + j*(-354) --51 + j*(512) -540 + j*(-234) --161 + j*(-114) -349 + j*(-91) --20 + j*(290) --208 + j*(-203) --25 + j*(161) --315 + j*(373) -286 + j*(-8) -125 + j*(395) --95 + j*(53) -332 + j*(-238) --211 + j*(-252) --69 + j*(-207) --617 + j*(268) --103 + j*(356) --131 + j*(393) --310 + j*(-280) --245 + j*(-274) --2 + j*(-759) --375 + j*(-166) --215 + j*(182) -315 + j*(230) --190 + j*(158) --446 + j*(333) -226 + j*(355) -344 + j*(-258) -16 + j*(-428) --372 + j*(301) -393 + j*(189) -293 + j*(-177) -455 + j*(-136) --35 + j*(-170) -16 + j*(-351) --16 + j*(-304) --127 + j*(205) --550 + j*(-288) --10 + j*(-56) --173 + j*(-178) --307 + j*(164) --329 + j*(175) --215 + j*(-426) -397 + j*(211) -289 + j*(-257) --272 + j*(23) --107 + j*(-281) -179 + j*(168) -26 + j*(-535) -23 + j*(234) -302 + j*(392) --164 + j*(-396) -52 + j*(231) -194 + j*(-21) --352 + j*(-203) --338 + j*(146) --677 + j*(-162) --191 + j*(-365) --387 + j*(493) --414 + j*(242) --103 + j*(243) --315 + j*(-6) --612 + j*(210) -41 + j*(-360) --133 + j*(-148) --368 + j*(241) -54 + j*(-62) -398 + j*(-445) --71 + j*(-591) -98 + j*(273) --729 + j*(338) --323 + j*(-267) -355 + j*(-348) -163 + j*(510) -508 + j*(-466) --651 + j*(-209) -189 + j*(168) -487 + j*(150) -364 + j*(111) -267 + j*(-54) -427 + j*(211) --412 + j*(594) --238 + j*(-31) --233 + j*(328) -192 + j*(115) -305 + j*(297) -484 + j*(436) --35 + j*(180) --129 + j*(-513) --51 + j*(-513) --398 + j*(-67) -162 + j*(373) -638 + j*(376) -641 + j*(-561) --204 + j*(-426) -551 + j*(-218) --161 + j*(556) -474 + j*(226) --243 + j*(-293) -16 + j*(-136) --474 + j*(-295) --490 + j*(-260) -252 + j*(-169) --363 + j*(209) --151 + j*(457) --361 + j*(-232) --168 + j*(460) -32 + j*(-496) --92 + j*(-243) --503 + j*(-238) -367 + j*(148) --56 + j*(258) --156 + j*(98) --250 + j*(-78) --107 + j*(-18) -298 + j*(257) --404 + j*(-225) --339 + j*(-220) --61 + j*(-391) --600 + j*(-141) -304 + j*(-457) --280 + j*(146) -206 + j*(421) -355 + j*(709) -153 + j*(225) -124 + j*(-206) -373 + j*(-447) --442 + j*(88) -269 + j*(-115) --335 + j*(-300) --158 + j*(-78) --320 + j*(-414) -491 + j*(-345) -559 + j*(252) --67 + j*(-332) --394 + j*(-370) -242 + j*(-639) --349 + j*(286) -98 + j*(57) -506 + j*(286) -117 + j*(-76) --506 + j*(47) --100 + j*(156) --59 + j*(-168) -162 + j*(363) --142 + j*(298) -110 + j*(139) -163 + j*(184) --107 + j*(-296) -40 + j*(231) --26 + j*(-117) --184 + j*(8) -156 + j*(-24) --98 + j*(-288) -192 + j*(-55) --138 + j*(-66) -161 + j*(276) -337 + j*(-55) -122 + j*(-122) -233 + j*(-233) --29 + j*(-118) --36 + j*(0) --259 + j*(5) -63 + j*(18) --158 + j*(-301) --95 + j*(-240) -549 + j*(309) -184 + j*(53) --141 + j*(328) --11 + j*(258) --41 + j*(237) --107 + j*(35) --265 + j*(-267) -205 + j*(-198) --274 + j*(284) --211 + j*(-33) --326 + j*(-124) --64 + j*(-79) --161 + j*(-294) -122 + j*(32) --248 + j*(-27) --3 + j*(-115) --145 + j*(-153) --308 + j*(35) -138 + j*(-127) --254 + j*(-220) --139 + j*(49) --33 + j*(-45) -41 + j*(23) -4 + j*(-356) --192 + j*(50) --81 + j*(200) -157 + j*(266) -110 + j*(252) -51 + j*(-231) --297 + j*(-110) --142 + j*(-7) --208 + j*(13) --236 + j*(-299) --43 + j*(190) -312 + j*(-10) -157 + j*(-322) -171 + j*(-177) --15 + j*(-80) --320 + j*(103) --58 + j*(208) -192 + j*(-77) -424 + j*(-43) -83 + j*(56) -218 + j*(83) -46 + j*(-98) --73 + j*(74) --149 + j*(35) --199 + j*(47) --54 + j*(-18) --68 + j*(136) -327 + j*(240) --45 + j*(337) --107 + j*(-88) --52 + j*(224) -238 + j*(58) --213 + j*(-77) -105 + j*(56) -163 + j*(-331) -119 + j*(-413) --66 + j*(-121) --112 + j*(176) -93 + j*(35) -199 + j*(98) -177 + j*(-56) --216 + j*(-6) --44 + j*(-34) --244 + j*(-201) -53 + j*(-68) -133 + j*(149) -85 + j*(179) --88 + j*(-4) --91 + j*(28) --173 + j*(16) --13 + j*(135) --147 + j*(120) --85 + j*(-152) -24 + j*(-194) --226 + j*(-117) --8 + j*(120) -301 + j*(350) -110 + j*(-192) --210 + j*(-33) --57 + j*(-59) --57 + j*(-199) -71 + j*(-110) -6 + j*(-235) --84 + j*(100) -38 + j*(-43) --40 + j*(151) --187 + j*(224) --156 + j*(138) -148 + j*(-41) -204 + j*(-564) -144 + j*(-85) -16 + j*(-325) --55 + j*(78) --21 + j*(-2) -77 + j*(152) --99 + j*(-4) --256 + j*(228) -221 + j*(0) --71 + j*(226) --83 + j*(-78) --5 + j*(173) --42 + j*(-68) -116 + j*(-40) -44 + j*(-258) --39 + j*(-39) --7 + j*(-173) --223 + j*(-71) -40 + j*(89) --86 + j*(-344) --243 + j*(190) -286 + j*(48) --284 + j*(227) -156 + j*(98) -180 + j*(-112) --327 + j*(-141) -180 + j*(11) --76 + j*(-96) --55 + j*(-71) --104 + j*(-48) -276 + j*(-40) --4 + j*(-30) -281 + j*(-175) -425 + j*(192) -33 + j*(-87) -279 + j*(42) --97 + j*(-129) -76 + j*(-5) -26 + j*(69) -48 + j*(-472) --218 + j*(-209) --143 + j*(-159) --59 + j*(1) -221 + j*(25) --95 + j*(32) --69 + j*(79) -95 + j*(-206) -159 + j*(-54) --121 + j*(107) --23 + j*(33) --68 + j*(-163) -40 + j*(-171) -190 + j*(-384) --162 + j*(-95) -23 + j*(-211) --136 + j*(0) --46 + j*(-2) -381 + j*(-231) -128 + j*(-233) --30 + j*(-272) --98 + j*(86) --109 + j*(-287) --30 + j*(-47) --94 + j*(235) --144 + j*(0) -257 + j*(210) --68 + j*(-23) -195 + j*(123) --221 + j*(122) -244 + j*(110) --126 + j*(-84) -59 + j*(-195) --64 + j*(305) -186 + j*(74) -85 + j*(-304) --126 + j*(96) -245 + j*(165) -23 + j*(-156) -267 + j*(-207) --306 + j*(-105) --195 + j*(131) --52 + j*(-120) -13 + j*(-123) --27 + j*(-401) -51 + j*(-105) --214 + j*(121) --68 + j*(-316) -64 + j*(83) --260 + j*(-67) --200 + j*(66) --270 + j*(108) --496 + j*(-64) --40 + j*(-259) --36 + j*(365) -29 + j*(61) -271 + j*(139) --46 + j*(-204) -112 + j*(301) -73 + j*(-66) -211 + j*(-33) -24 + j*(161) --153 + j*(-43) -4 + j*(-89) -107 + j*(202) --52 + j*(-315) -23 + j*(59) --80 + j*(-99) -115 + j*(-133) -127 + j*(-4) -56 + j*(278) --90 + j*(17) --215 + j*(176) -39 + j*(-146) --180 + j*(21) --135 + j*(146) -297 + j*(-195) --173 + j*(13) -227 + j*(153) -107 + j*(-227) --42 + j*(94) --177 + j*(176) -157 + j*(40) --243 + j*(30) --65 + j*(-271) --162 + j*(218) -574 + j*(-124) -64 + j*(-87) --106 + j*(21) --64 + j*(-85) -105 + j*(78) -170 + j*(252) -171 + j*(-236) -301 + j*(157) -257 + j*(-142) --198 + j*(127) -8 + j*(402) --31 + j*(137) --168 + j*(-62) -331 + j*(-171) -95 + j*(-11) -260 + j*(-33) -358 + j*(-293) --36 + j*(63) --6 + j*(151) -177 + j*(-247) -60 + j*(-130) -199 + j*(49) --54 + j*(83) -0 + j*(27) --158 + j*(-120) -190 + j*(-147) --168 + j*(138) -161 + j*(-16) --5 + j*(14) --260 + j*(-122) --65 + j*(118) --136 + j*(-20) -97 + j*(0) --78 + j*(0) -89 + j*(-169) -141 + j*(-215) --119 + j*(191) -114 + j*(-15) --366 + j*(300) --267 + j*(373) --71 + j*(211) -220 + j*(136) -3 + j*(91) -170 + j*(275) -159 + j*(-59) --163 + j*(-139) --148 + j*(-9) -161 + j*(321) -167 + j*(26) --87 + j*(-114) --143 + j*(33) -47 + j*(145) -30 + j*(-80) -64 + j*(-204) -70 + j*(-93) --183 + j*(37) --71 + j*(-274) --81 + j*(-93) -243 + j*(197) --277 + j*(-307) --103 + j*(-231) -32 + j*(168) -18 + j*(-4) -320 + j*(267) --28 + j*(-4) -64 + j*(195) --165 + j*(-17) --72 + j*(-80) --83 + j*(236) --95 + j*(-298) --310 + j*(4) -43 + j*(-100) -219 + j*(-225) -99 + j*(184) --158 + j*(-57) --32 + j*(-35) --405 + j*(-144) -329 + j*(9) -191 + j*(47) --65 + j*(98) --28 + j*(-207) --56 + j*(103) --9 + j*(30) --59 + j*(249) --161 + j*(-89) -105 + j*(-37) --136 + j*(-25) --461 + j*(-19) -238 + j*(-184) --49 + j*(-118) --171 + j*(-199) -208 + j*(-146) --117 + j*(-15) --72 + j*(192) -351 + j*(-381) --117 + j*(-57) --37 + j*(-335) --4 + j*(-30) --269 + j*(-141) -351 + j*(107) --214 + j*(-186) -154 + j*(-385) --10 + j*(-100) --200 + j*(-194) -120 + j*(-171) -16 + j*(-36) --6 + j*(64) -53 + j*(-182) --21 + j*(66) --244 + j*(-162) --187 + j*(107) -257 + j*(6) -254 + j*(183) -21 + j*(-123) --260 + j*(-235) --198 + j*(208) -67 + j*(-178) --156 + j*(171) -23 + j*(-328) -50 + j*(-82) -273 + j*(91) --465 + j*(11) --252 + j*(-271) -66 + j*(159) --349 + j*(-22) --38 + j*(-395) -63 + j*(-30) --83 + j*(-186) --167 + j*(-312) -231 + j*(17) -168 + j*(-475) -216 + j*(-16) --141 + j*(-285) --185 + j*(72) -88 + j*(-3) --132 + j*(-122) -63 + j*(245) -158 + j*(-104) --301 + j*(-276) --28 + j*(226) -129 + j*(40) --146 + j*(-64) --306 + j*(-209) -35 + j*(50) -390 + j*(30) --264 + j*(-94) --201 + j*(30) -4 + j*(21) --325 + j*(-134) --270 + j*(-317) -402 + j*(4) --135 + j*(181) -221 + j*(69) --272 + j*(-63) --79 + j*(169) --31 + j*(249) -25 + j*(238) -69 + j*(39) -38 + j*(119) --13 + j*(54) -218 + j*(-204) --118 + j*(-271) --123 + j*(-87) --215 + j*(-211) -8 + j*(-20) --113 + j*(-134) -118 + j*(330) -184 + j*(52) --52 + j*(8) -170 + j*(-322) -59 + j*(-35) --247 + j*(372) --42 + j*(-73) -119 + j*(111) --25 + j*(-49) --2 + j*(-87) --310 + j*(-179) -250 + j*(70) --49 + j*(18) -100 + j*(-186) --135 + j*(28) --71 + j*(153) -45 + j*(428) -3 + j*(-249) --119 + j*(111) -321 + j*(223) -25 + j*(-214) -199 + j*(-301) -36 + j*(-147) -182 + j*(-100) -138 + j*(-7) --115 + j*(-452) -147 + j*(52) -31 + j*(-32) --359 + j*(243) --57 + j*(-26) -288 + j*(-342) --114 + j*(362) --314 + j*(-102) --130 + j*(-46) -90 + j*(184) -46 + j*(-83) --231 + j*(151) --25 + j*(-37) --51 + j*(-51) --491 + j*(88) --45 + j*(141) -62 + j*(-93) --115 + j*(189) --167 + j*(556) --111 + j*(-173) --148 + j*(-122) --70 + j*(-202) -226 + j*(315) -47 + j*(82) -107 + j*(92) --71 + j*(159) --201 + j*(96) --279 + j*(312) -178 + j*(-182) -21 + j*(30) -93 + j*(-142) -330 + j*(-162) -88 + j*(49) -91 + j*(118) --88 + j*(186) -157 + j*(76) --174 + j*(79) -172 + j*(-34) -175 + j*(-133) --195 + j*(-25) -100 + j*(-73) -237 + j*(213) --206 + j*(-190) -209 + j*(-362) --407 + j*(407) --188 + j*(88) --54 + j*(264) --172 + j*(-100) -127 + j*(-121) --132 + j*(-37) --45 + j*(96) -221 + j*(111) -167 + j*(-11) -57 + j*(19) -119 + j*(-85) --74 + j*(69) -12 + j*(-302) --69 + j*(-177) --21 + j*(181) --117 + j*(157) -82 + j*(328) -393 + j*(29) -186 + j*(77) -371 + j*(-147) -93 + j*(-47) --169 + j*(-63) --48 + j*(215) -9 + j*(-59) -73 + j*(-226) --295 + j*(-11) --247 + j*(158) --114 + j*(-120) --83 + j*(-57) -53 + j*(-2) --151 + j*(-27) --251 + j*(-245) --193 + j*(-12) -31 + j*(-63) -235 + j*(208) -53 + j*(-342) -138 + j*(-112) -93 + j*(-262) -5 + j*(65) --266 + j*(-119) --149 + j*(-166) --25 + j*(38) -184 + j*(7) --290 + j*(-71) -157 + j*(293) --90 + j*(-56) -458 + j*(-84) --99 + j*(-19) -164 + j*(153) -224 + j*(174) --101 + j*(-18) --81 + j*(154) -158 + j*(154) --127 + j*(-254) -175 + j*(-91) -292 + j*(21) --170 + j*(0) -148 + j*(-99) --146 + j*(133) -136 + j*(121) -114 + j*(-186) --29 + j*(60) -39 + j*(108) --83 + j*(-29) -25 + j*(254) --4 + j*(-291) -28 + j*(199) --47 + j*(-40) --95 + j*(203) --223 + j*(18) -109 + j*(-144) --82 + j*(-18) -148 + j*(302) -42 + j*(58) -291 + j*(205) -69 + j*(25) --135 + j*(-63) -73 + j*(-18) --325 + j*(-216) --100 + j*(62) --17 + j*(-175) --198 + j*(93) --25 + j*(216) -92 + j*(-165) -122 + j*(-248) -165 + j*(166) -121 + j*(85) -81 + j*(-57) -105 + j*(167) -211 + j*(-134) -18 + j*(-106) --33 + j*(-170) -73 + j*(-61) -286 + j*(-19) -2 + j*(286) --436 + j*(426) --118 + j*(-88) --47 + j*(-100) --127 + j*(266) -58 + j*(-47) --15 + j*(210) -117 + j*(130) --325 + j*(146) -91 + j*(108) -127 + j*(-89) -41 + j*(-191) --69 + j*(283) --24 + j*(-206) --237 + j*(-129) -24 + j*(1) --15 + j*(188) -159 + j*(-438) --153 + j*(177) -91 + j*(84) -196 + j*(99) --199 + j*(-139) --26 + j*(161) --98 + j*(-145) -139 + j*(208) -8 + j*(-177) -106 + j*(83) -107 + j*(-57) --309 + j*(-213) --96 + j*(16) -88 + j*(-123) --114 + j*(145) -238 + j*(-22) -46 + j*(-329) -156 + j*(-65) --183 + j*(112) -61 + j*(-93) -11 + j*(154) -47 + j*(8) --110 + j*(-246) --185 + j*(-25) -383 + j*(-152) -6 + j*(-38) -162 + j*(-64) --345 + j*(178) --4 + j*(-176) --76 + j*(49) -50 + j*(-157) --230 + j*(-141) --103 + j*(-71) -286 + j*(134) --431 + j*(-79) -153 + j*(34) --320 + j*(-55) -178 + j*(292) --25 + j*(-117) -189 + j*(57) -158 + j*(105) --108 + j*(-551) -170 + j*(-34) --298 + j*(-87) -187 + j*(-165) -69 + j*(59) --166 + j*(453) -111 + j*(-119) -172 + j*(-110) --185 + j*(158) --131 + j*(-267) --54 + j*(-285) --57 + j*(65) -94 + j*(-38) -382 + j*(-139) --119 + j*(-199) --252 + j*(48) --190 + j*(421) --119 + j*(30) -165 + j*(236) -77 + j*(42) -14 + j*(210) --52 + j*(-196) -144 + j*(-216) -28 + j*(99) --242 + j*(151) --19 + j*(-17) -62 + j*(-230) -146 + j*(130) --67 + j*(-202) -158 + j*(-134) --318 + j*(192) -48 + j*(-28) --322 + j*(180) --263 + j*(187) -58 + j*(226) --1 + j*(96) -8 + j*(304) --31 + j*(-8) -214 + j*(-35) --35 + j*(-71) --22 + j*(-124) --321 + j*(-234) -305 + j*(-367) --170 + j*(-57) --206 + j*(124) --64 + j*(-117) -35 + j*(-8) --74 + j*(-139) --81 + j*(200) -355 + j*(189) -115 + j*(158) --22 + j*(1) --117 + j*(319) -48 + j*(193) --66 + j*(-28) --78 + j*(-221) -77 + j*(204) --308 + j*(187) --373 + j*(223) --246 + j*(224) -277 + j*(147) -64 + j*(-37) --13 + j*(-129) -6 + j*(-28) -80 + j*(15) -173 + j*(60) --112 + j*(98) --279 + j*(-98) -103 + j*(29) -115 + j*(13) -49 + j*(-102) -233 + j*(81) -189 + j*(-76) -192 + j*(52) --54 + j*(-86) --33 + j*(-18) --248 + j*(105) -76 + j*(177) -433 + j*(-158) --190 + j*(-6) --139 + j*(93) --57 + j*(-262) -165 + j*(-156) -305 + j*(-173) --5 + j*(323) -33 + j*(335) --156 + j*(-53) --235 + j*(111) --19 + j*(78) --34 + j*(-106) -254 + j*(62) --130 + j*(185) -5 + j*(-9) -53 + j*(-91) --107 + j*(357) --16 + j*(-24) -41 + j*(-177) --18 + j*(135) -102 + j*(223) --88 + j*(87) -173 + j*(251) --35 + j*(-85) --260 + j*(-141) -13 + j*(35) -235 + j*(136) -45 + j*(109) -57 + j*(-5) -59 + j*(-38) -148 + j*(78) -134 + j*(-247) --215 + j*(40) -243 + j*(-28) -42 + j*(-71) --59 + j*(-18) -63 + j*(-50) --286 + j*(-103) --140 + j*(-54) -43 + j*(-92) -117 + j*(-78) -58 + j*(-70) --2 + j*(-187) -33 + j*(1) --328 + j*(189) --151 + j*(-17) -70 + j*(56) --33 + j*(110) --56 + j*(-232) -139 + j*(211) -68 + j*(-8) --23 + j*(-332) --84 + j*(-69) --124 + j*(-66) -238 + j*(-9) -165 + j*(-138) -117 + j*(153) --3 + j*(-95) -252 + j*(-83) --146 + j*(81) --163 + j*(-2) -231 + j*(206) -103 + j*(-237) -14 + j*(-40) -187 + j*(175) --88 + j*(171) -66 + j*(202) -71 + j*(-172) --182 + j*(-47) --193 + j*(96) -158 + j*(197) --11 + j*(-202) --110 + j*(86) --76 + j*(-20) -23 + j*(-204) --110 + j*(228) -30 + j*(-39) -182 + j*(-27) -104 + j*(30) --421 + j*(55) --124 + j*(-89) -275 + j*(140) --114 + j*(65) -188 + j*(221) --515 + j*(152) --315 + j*(-170) -1 + j*(-225) -294 + j*(14) -202 + j*(6) -255 + j*(-163) --30 + j*(-192) --179 + j*(141) -148 + j*(-154) --74 + j*(-300) --235 + j*(18) -247 + j*(-79) -177 + j*(-129) --186 + j*(182) --50 + j*(-11) -356 + j*(-52) -148 + j*(-117) -136 + j*(99) -93 + j*(-328) --4 + j*(26) -7 + j*(-222) --58 + j*(-41) -236 + j*(106) --535 + j*(89) -356 + j*(320) --111 + j*(38) -58 + j*(-325) --165 + j*(103) --176 + j*(-89) --93 + j*(-48) --6 + j*(69) -110 + j*(-194) --19 + j*(1) -18 + j*(-311) -407 + j*(-1) -64 + j*(161) -142 + j*(-227) --356 + j*(-335) -195 + j*(366) --200 + j*(-170) -160 + j*(194) --43 + j*(-305) -168 + j*(-30) -221 + j*(146) --13 + j*(194) -366 + j*(-336) --265 + j*(107) --216 + j*(133) --73 + j*(124) --288 + j*(-79) --6 + j*(78) -359 + j*(126) --62 + j*(180) -205 + j*(-325) --21 + j*(-49) -54 + j*(-180) -77 + j*(-340) --77 + j*(-49) --87 + j*(166) -129 + j*(115) --167 + j*(25) -192 + j*(-13) -395 + j*(-304) -358 + j*(-41) -8 + j*(135) --91 + j*(-146) --103 + j*(-84) -136 + j*(98) --123 + j*(-60) -298 + j*(-141) --117 + j*(-283) -335 + j*(-21) -143 + j*(-44) --249 + j*(-75) -11 + j*(47) --146 + j*(-163) -185 + j*(232) -313 + j*(59) --227 + j*(-141) --214 + j*(-50) --64 + j*(143) -73 + j*(-165) -185 + j*(-30) -55 + j*(48) --152 + j*(-82) --35 + j*(-16) -49 + j*(-21) -4 + j*(313) -279 + j*(42) -48 + j*(-219) -40 + j*(37) --71 + j*(99) --75 + j*(-37) -11 + j*(-197) -118 + j*(40) --59 + j*(45) --106 + j*(79) -84 + j*(-100) --6 + j*(-39) --144 + j*(418) -52 + j*(351) -187 + j*(264) --26 + j*(25) --1 + j*(-44) --93 + j*(515) -63 + j*(-93) -296 + j*(78) --311 + j*(363) -4 + j*(-178) -63 + j*(265) --204 + j*(-132) -59 + j*(-104) --294 + j*(8) --167 + j*(76) --74 + j*(288) -105 + j*(-91) -105 + j*(21) -19 + j*(-169) -132 + j*(-124) -83 + j*(43) --302 + j*(-35) -155 + j*(206) -151 + j*(100) --242 + j*(188) -1 + j*(269) --30 + j*(-129) -387 + j*(-134) -135 + j*(89) -15 + j*(-282) -130 + j*(-124) -387 + j*(10) -136 + j*(74) --83 + j*(-74) --450 + j*(-119) --84 + j*(-28) --62 + j*(161) --76 + j*(-78) -75 + j*(-597) -273 + j*(80) --9 + j*(109) -4 + j*(62) -106 + j*(62) -105 + j*(199) --132 + j*(158) --21 + j*(5) --142 + j*(98) --282 + j*(170) -180 + j*(131) -211 + j*(-172) --155 + j*(192) --393 + j*(-5) --84 + j*(-328) --30 + j*(-112) --71 + j*(-198) -120 + j*(-38) --223 + j*(-73) --11 + j*(196) -170 + j*(76) --129 + j*(67) --121 + j*(-35) --66 + j*(103) --183 + j*(148) --215 + j*(-71) --158 + j*(-179) --211 + j*(13) --78 + j*(201) -245 + j*(132) --139 + j*(-11) --58 + j*(204) --103 + j*(-175) --12 + j*(73) --52 + j*(-126) -29 + j*(40) -67 + j*(-36) -18 + j*(-4) -15 + j*(-45) -268 + j*(-138) -62 + j*(25) --344 + j*(-20) -16 + j*(93) --122 + j*(119) --44 + j*(-205) -137 + j*(-150) -197 + j*(-11) -56 + j*(-64) -25 + j*(-168) -112 + j*(141) --144 + j*(29) --170 + j*(-252) --190 + j*(-37) --8 + j*(-127) --10 + j*(247) -193 + j*(-303) --122 + j*(-218) -165 + j*(-90) -28 + j*(-100) -31 + j*(19) --96 + j*(-121) --98 + j*(30) --281 + j*(-203) -250 + j*(-42) --244 + j*(109) --47 + j*(-231) -16 + j*(-291) -40 + j*(-218) --300 + j*(34) --152 + j*(173) --74 + j*(73) --23 + j*(-93) --45 + j*(-342) -24 + j*(-52) --193 + j*(183) --151 + j*(-307) --26 + j*(24) -207 + j*(-115) --58 + j*(139) --33 + j*(-112) --409 + j*(149) --1 + j*(-136) --288 + j*(-105) --30 + j*(-198) -187 + j*(39) -71 + j*(33) --371 + j*(64) --27 + j*(-169) -40 + j*(4) --234 + j*(72) --243 + j*(-18) -29 + j*(71) -189 + j*(-243) --201 + j*(-335) --214 + j*(-97) --161 + j*(185) --247 + j*(45) --260 + j*(-303) --206 + j*(245) --127 + j*(12) -49 + j*(156) --52 + j*(-3) -193 + j*(69) -203 + j*(62) -111 + j*(-100) --105 + j*(-18) -25 + j*(-121) --134 + j*(104) --275 + j*(233) -100 + j*(-326) --230 + j*(-73) -139 + j*(-256) -300 + j*(23) --189 + j*(-491) -137 + j*(-88) -133 + j*(-263) --106 + j*(-373) --18 + j*(-103) --98 + j*(223) --4 + j*(-18) -6 + j*(266) -60 + j*(-30) --188 + j*(-150) --118 + j*(40) --140 + j*(-16) -88 + j*(59) --22 + j*(-28) -110 + j*(-66) -160 + j*(-157) -139 + j*(31) -19 + j*(-97) -69 + j*(101) --49 + j*(172) -245 + j*(-80) -14 + j*(274) --71 + j*(1) --33 + j*(29) --208 + j*(66) -184 + j*(227) --239 + j*(-216) -127 + j*(-18) -469 + j*(177) --91 + j*(263) -4 + j*(46) --212 + j*(102) -25 + j*(-23) -153 + j*(10) --97 + j*(-8) --236 + j*(-30) --46 + j*(-418) --104 + j*(288) -78 + j*(-39) -136 + j*(1) -43 + j*(-76) -34 + j*(-223) -110 + j*(-4) -146 + j*(-64) --5 + j*(45) -89 + j*(44) --12 + j*(-76) --5 + j*(-25) -20 + j*(243) -47 + j*(-218) --81 + j*(71) --73 + j*(187) -314 + j*(94) --119 + j*(-69) -136 + j*(88) -158 + j*(75) --196 + j*(-190) --5 + j*(-135) -134 + j*(228) --108 + j*(-257) --16 + j*(414) --16 + j*(96) -151 + j*(163) -93 + j*(4) --204 + j*(-71) --107 + j*(213) -187 + j*(26) --30 + j*(242) -89 + j*(-8) -4 + j*(-206) --54 + j*(-242) -110 + j*(-37) --175 + j*(-238) --148 + j*(15) -208 + j*(-152) --28 + j*(-235) --183 + j*(-280) -189 + j*(-124) --19 + j*(8) --250 + j*(-168) --24 + j*(-89) --247 + j*(140) -216 + j*(385) -88 + j*(-119) -356 + j*(-173) -4 + j*(145) --193 + j*(-115) -109 + j*(-45) -203 + j*(172) --103 + j*(337) --80 + j*(187) --129 + j*(179) -158 + j*(-235) --52 + j*(-272) --91 + j*(327) --25 + j*(117) --143 + j*(-141) -92 + j*(310) -129 + j*(33) --202 + j*(159) -86 + j*(43) --43 + j*(69) --130 + j*(-140) --139 + j*(371) --1 + j*(92) --301 + j*(-141) -170 + j*(83) -6 + j*(-224) --183 + j*(132) --187 + j*(74) -141 + j*(-238) --102 + j*(346) --230 + j*(298) -71 + j*(280) --360 + j*(311) --85 + j*(173) -117 + j*(-69) -23 + j*(314) --179 + j*(234) -95 + j*(8) -18 + j*(-133) --137 + j*(-108) -115 + j*(122) --23 + j*(-101) -18 + j*(2) -96 + j*(-134) -21 + j*(3) -373 + j*(-148) -162 + j*(41) -240 + j*(244) --114 + j*(192) -86 + j*(-23) --55 + j*(67) --188 + j*(163) --23 + j*(10) -18 + j*(-76) --27 + j*(21) -163 + j*(198) --44 + j*(33) -70 + j*(66) --132 + j*(356) --43 + j*(-99) --134 + j*(165) -225 + j*(-81) --55 + j*(-30) -143 + j*(88) -64 + j*(-105) --44 + j*(-93) --69 + j*(-28) --184 + j*(-154) --315 + j*(184) -49 + j*(-148) --220 + j*(91) --91 + j*(-29) --177 + j*(-166) -35 + j*(86) --190 + j*(-197) --281 + j*(-106) --211 + j*(-90) --185 + j*(27) -50 + j*(298) -71 + j*(-78) -268 + j*(-33) -79 + j*(-139) -218 + j*(125) -400 + j*(190) --83 + j*(17) --129 + j*(385) --5 + j*(-299) --202 + j*(-363) -233 + j*(24) -13 + j*(-80) --256 + j*(-156) -194 + j*(-125) -233 + j*(104) --206 + j*(145) --181 + j*(137) --342 + j*(253) -91 + j*(13) --117 + j*(164) --138 + j*(58) -227 + j*(-179) --38 + j*(42) --46 + j*(-65) -98 + j*(302) --18 + j*(167) -135 + j*(136) -111 + j*(16) --107 + j*(-140) -69 + j*(-180) -69 + j*(-49) --100 + j*(190) --161 + j*(302) --57 + j*(261) -78 + j*(-50) -62 + j*(45) -298 + j*(24) -65 + j*(288) --132 + j*(4) -186 + j*(4) -53 + j*(84) --94 + j*(177) -258 + j*(-5) -82 + j*(-281) -282 + j*(295) -119 + j*(-278) --65 + j*(-95) --216 + j*(-46) -116 + j*(105) -13 + j*(287) -105 + j*(165) -221 + j*(-129) -27 + j*(115) --284 + j*(5) --20 + j*(190) -39 + j*(128) --301 + j*(-53) --198 + j*(-95) --39 + j*(129) --34 + j*(-30) --25 + j*(280) -134 + j*(176) --54 + j*(-99) -64 + j*(-139) --147 + j*(191) -77 + j*(-8) --140 + j*(1) -29 + j*(6) --252 + j*(-90) -66 + j*(-373) --273 + j*(177) --53 + j*(-73) -426 + j*(209) -303 + j*(-223) -230 + j*(78) --146 + j*(-151) -32 + j*(169) -408 + j*(48) -149 + j*(54) --18 + j*(-1) -320 + j*(122) --23 + j*(28) -89 + j*(-202) -33 + j*(-117) -274 + j*(-25) -23 + j*(-18) --88 + j*(-291) --51 + j*(407) --50 + j*(18) --4 + j*(-36) -115 + j*(124) --13 + j*(150) -223 + j*(-66) --48 + j*(108) --82 + j*(-92) -40 + j*(219) --216 + j*(148) --187 + j*(-291) --45 + j*(56) -185 + j*(47) -94 + j*(-248) --107 + j*(-1) --199 + j*(-47) -20 + j*(60) -117 + j*(141) --151 + j*(-326) -51 + j*(-210) -121 + j*(-66) --40 + j*(-173) --83 + j*(-199) --54 + j*(-74) -83 + j*(-98) -243 + j*(170) -217 + j*(-255) -242 + j*(-443) --148 + j*(-34) -42 + j*(201) -29 + j*(-47) --98 + j*(-1) -45 + j*(141) --148 + j*(-74) -161 + j*(-137) -116 + j*(169) -49 + j*(-519) -9 + j*(-118) -144 + j*(169) --106 + j*(77) --124 + j*(-10) --298 + j*(303) -268 + j*(-8) -44 + j*(-12) -165 + j*(-390) --98 + j*(-107) -199 + j*(197) -194 + j*(49) --206 + j*(412) -68 + j*(-216) -274 + j*(139) --237 + j*(60) -85 + j*(285) -4 + j*(-130) -168 + j*(-20) -284 + j*(175) -316 + j*(-301) -62 + j*(148) -54 + j*(-270) -95 + j*(266) --95 + j*(-28) --46 + j*(29) --254 + j*(-30) --159 + j*(117) --9 + j*(-117) --64 + j*(-76) -59 + j*(19) --45 + j*(-144) --358 + j*(-110) --302 + j*(218) -140 + j*(335) -233 + j*(12) -386 + j*(96) --37 + j*(-218) --187 + j*(-46) -16 + j*(290) -59 + j*(18) -158 + j*(-102) -104 + j*(-3) --23 + j*(204) -131 + j*(161) -105 + j*(339) --226 + j*(-220) --144 + j*(202) --95 + j*(-191) --44 + j*(49) -69 + j*(-114) --105 + j*(221) -12 + j*(58) -264 + j*(-68) --21 + j*(88) --357 + j*(15) --122 + j*(-136) --35 + j*(129) -139 + j*(-16) --175 + j*(-110) -24 + j*(67) -17 + j*(56) --100 + j*(-48) --75 + j*(-260) --28 + j*(-51) -52 + j*(-117) -445 + j*(41) -35 + j*(159) --68 + j*(112) --208 + j*(158) --182 + j*(-253) --3 + j*(-115) --30 + j*(371) -8 + j*(30) --223 + j*(-93) -274 + j*(57) --313 + j*(-148) -244 + j*(195) -10 + j*(-305) -296 + j*(88) -7 + j*(87) --40 + j*(91) --315 + j*(-76) --16 + j*(88) --83 + j*(-124) --98 + j*(-20) --94 + j*(-92) --143 + j*(-262) --87 + j*(49) -252 + j*(-49) --119 + j*(354) -134 + j*(46) --167 + j*(-270) --130 + j*(-144) -103 + j*(151) --87 + j*(243) -70 + j*(132) --128 + j*(2) -58 + j*(114) -215 + j*(14) --81 + j*(183) -37 + j*(65) --151 + j*(38) --92 + j*(75) --240 + j*(-64) --23 + j*(-105) --359 + j*(-221) --107 + j*(18) -88 + j*(-301) --308 + j*(542) --77 + j*(-313) -221 + j*(-117) --18 + j*(-79) -118 + j*(-240) --389 + j*(-11) -57 + j*(0) --142 + j*(-67) --115 + j*(-76) -39 + j*(-61) -182 + j*(0) --65 + j*(46) -57 + j*(-47) --304 + j*(33) --430 + j*(489) --425 + j*(47) -261 + j*(597) --67 + j*(314) --337 + j*(167) --143 + j*(-90) --353 + j*(-21) --335 + j*(162) -605 + j*(390) --31 + j*(-196) --340 + j*(-206) --275 + j*(-161) --332 + j*(120) -422 + j*(202) -316 + j*(192) --141 + j*(535) --296 + j*(-251) -209 + j*(-497) --286 + j*(-75) -165 + j*(470) --82 + j*(273) -99 + j*(267) --262 + j*(188) --15 + j*(172) --30 + j*(403) -212 + j*(272) --204 + j*(-431) --351 + j*(-269) -589 + j*(204) -311 + j*(-122) -391 + j*(-222) --371 + j*(286) --566 + j*(-589) -202 + j*(-261) --151 + j*(-124) -474 + j*(-434) -272 + j*(-49) -359 + j*(75) -129 + j*(-83) --320 + j*(-96) -140 + j*(-76) --211 + j*(-550) -305 + j*(417) --412 + j*(64) -226 + j*(-547) -407 + j*(-380) --83 + j*(-97) -396 + j*(-173) -255 + j*(-368) -213 + j*(-57) -313 + j*(110) -42 + j*(158) --93 + j*(-151) --267 + j*(12) --50 + j*(119) --161 + j*(-238) --6 + j*(-322) --392 + j*(-337) -472 + j*(-371) -142 + j*(421) --317 + j*(400) -447 + j*(-417) -487 + j*(-246) --265 + j*(420) --237 + j*(279) --163 + j*(188) --423 + j*(341) --38 + j*(-321) -492 + j*(101) --297 + j*(-282) --43 + j*(210) -247 + j*(262) -219 + j*(253) -446 + j*(250) --492 + j*(-336) -272 + j*(-373) -289 + j*(241) --71 + j*(-12) --334 + j*(684) --156 + j*(294) -219 + j*(168) -222 + j*(391) --127 + j*(585) -458 + j*(-467) -400 + j*(-296) --229 + j*(1) --195 + j*(130) --42 + j*(-72) --548 + j*(46) -168 + j*(17) --109 + j*(307) -274 + j*(-205) -181 + j*(-606) -23 + j*(216) --359 + j*(13) -91 + j*(288) --216 + j*(141) --315 + j*(-303) -165 + j*(450) --474 + j*(64) -450 + j*(-318) --443 + j*(348) -131 + j*(450) -259 + j*(401) --464 + j*(-486) -74 + j*(-565) --122 + j*(-119) -512 + j*(-184) --305 + j*(201) -199 + j*(-392) -158 + j*(-424) -156 + j*(43) --610 + j*(289) -172 + j*(-296) -47 + j*(297) --458 + j*(-441) -222 + j*(-376) --399 + j*(8) --208 + j*(371) --65 + j*(-204) --322 + j*(663) --438 + j*(-144) -144 + j*(123) -97 + j*(363) -164 + j*(-170) --237 + j*(167) -117 + j*(55) -342 + j*(-199) --254 + j*(226) --356 + j*(474) --164 + j*(171) -393 + j*(-431) --197 + j*(-47) -192 + j*(179) -183 + j*(-356) -377 + j*(-268) -465 + j*(407) --193 + j*(-66) --267 + j*(-235) -607 + j*(416) --198 + j*(310) -403 + j*(542) -182 + j*(-26) --594 + j*(-251) --167 + j*(-284) --265 + j*(667) -171 + j*(-404) -122 + j*(-467) --266 + j*(57) --361 + j*(-285) -348 + j*(23) --206 + j*(-553) --160 + j*(309) -491 + j*(283) --422 + j*(-171) --202 + j*(-250) --229 + j*(99) -183 + j*(95) -134 + j*(-175) -172 + j*(-517) -147 + j*(385) --446 + j*(392) -228 + j*(106) -90 + j*(-122) --284 + j*(-69) --255 + j*(-495) -99 + j*(-112) --347 + j*(-191) -355 + j*(173) --342 + j*(175) -407 + j*(-28) -223 + j*(-71) --313 + j*(26) -156 + j*(-120) -392 + j*(-379) --321 + j*(-26) --399 + j*(160) -187 + j*(228) --249 + j*(-415) -404 + j*(399) -198 + j*(253) -438 + j*(82) -479 + j*(237) -363 + j*(318) -576 + j*(-229) --667 + j*(-161) -300 + j*(-527) -92 + j*(596) --7 + j*(-363) --397 + j*(414) -142 + j*(220) -535 + j*(395) -306 + j*(418) --162 + j*(-406) -354 + j*(-330) --219 + j*(162) --331 + j*(-506) -496 + j*(225) -133 + j*(115) -214 + j*(218) -197 + j*(-316) -587 + j*(9) --30 + j*(397) --547 + j*(-593) -352 + j*(-108) --219 + j*(142) --383 + j*(286) --216 + j*(-329) -390 + j*(276) --157 + j*(-122) -236 + j*(122) -31 + j*(-37) -174 + j*(-285) -253 + j*(-253) -427 + j*(-403) --315 + j*(345) --428 + j*(-682) -15 + j*(-400) --339 + j*(496) --588 + j*(91) -229 + j*(-165) -529 + j*(296) -553 + j*(346) --144 + j*(66) --397 + j*(452) -445 + j*(406) --112 + j*(-163) -301 + j*(253) -296 + j*(274) -354 + j*(-94) --457 + j*(-530) --373 + j*(-168) --270 + j*(-178) --407 + j*(-224) -3 + j*(-22) -177 + j*(288) --476 + j*(31) --296 + j*(232) --331 + j*(-110) -429 + j*(-240) -385 + j*(-395) --89 + j*(326) -369 + j*(243) --419 + j*(30) -117 + j*(-298) --83 + j*(388) -427 + j*(119) --233 + j*(-222) --437 + j*(509) --329 + j*(-51) -184 + j*(238) -383 + j*(-150) -398 + j*(204) --277 + j*(-255) --166 + j*(105) -409 + j*(-567) --312 + j*(-180) -85 + j*(-119) --353 + j*(52) --416 + j*(-530) --59 + j*(-94) --454 + j*(-723) -321 + j*(148) --545 + j*(-355) --286 + j*(-40) -398 + j*(-600) -144 + j*(-344) -199 + j*(-606) --42 + j*(290) --328 + j*(-112) --199 + j*(-245) -303 + j*(-335) --484 + j*(-413) --314 + j*(98) --100 + j*(-88) --328 + j*(383) --117 + j*(33) -491 + j*(-299) -320 + j*(426) -124 + j*(320) --184 + j*(223) --165 + j*(-230) -280 + j*(-183) -67 + j*(-808) -104 + j*(177) -260 + j*(-230) -454 + j*(-49) -145 + j*(-433) --284 + j*(-306) -336 + j*(-199) --338 + j*(-395) -168 + j*(-86) --537 + j*(-232) --396 + j*(-558) -587 + j*(-207) -155 + j*(-412) --122 + j*(185) --648 + j*(-65) --167 + j*(-233) --371 + j*(308) --449 + j*(-25) -156 + j*(233) --207 + j*(243) --474 + j*(313) -325 + j*(6) --183 + j*(269) --344 + j*(-54) --98 + j*(325) -382 + j*(197) --304 + j*(-89) -100 + j*(-390) --471 + j*(-12) -237 + j*(255) -247 + j*(-138) --98 + j*(-78) -63 + j*(199) --258 + j*(-231) --470 + j*(-422) --224 + j*(378) -629 + j*(1) --255 + j*(-604) --100 + j*(478) --19 + j*(430) -663 + j*(213) -222 + j*(181) --127 + j*(270) -351 + j*(-373) -308 + j*(192) --149 + j*(240) -80 + j*(-377) -120 + j*(-112) --96 + j*(-182) --8 + j*(-73) -477 + j*(-154) --419 + j*(274) --496 + j*(256) --240 + j*(410) -150 + j*(-351) --243 + j*(-137) --11 + j*(-345) -100 + j*(197) -67 + j*(52) -247 + j*(276) -106 + j*(404) --426 + j*(-358) -161 + j*(-528) -211 + j*(233) --408 + j*(180) -334 + j*(464) -469 + j*(-114) -278 + j*(178) -86 + j*(-257) -78 + j*(-322) -457 + j*(-159) --275 + j*(328) --508 + j*(-10) -209 + j*(89) --301 + j*(291) --247 + j*(-146) -259 + j*(177) -83 + j*(-61) --369 + j*(-315) --206 + j*(-272) --194 + j*(53) -344 + j*(291) -242 + j*(-343) -433 + j*(-74) -424 + j*(423) --332 + j*(160) --345 + j*(675) -209 + j*(-36) --152 + j*(-247) --177 + j*(434) -312 + j*(317) -197 + j*(-103) --355 + j*(112) --69 + j*(-194) -400 + j*(118) -151 + j*(506) -386 + j*(-337) -451 + j*(228) -40 + j*(-25) -48 + j*(-194) --218 + j*(-320) -207 + j*(-124) --117 + j*(-141) -343 + j*(-224) -308 + j*(291) --247 + j*(-361) -511 + j*(32) -228 + j*(91) -380 + j*(302) -324 + j*(-119) --413 + j*(463) -292 + j*(281) --201 + j*(-165) --303 + j*(-211) --471 + j*(418) --69 + j*(-121) --607 + j*(274) -141 + j*(342) --339 + j*(-220) --51 + j*(-165) -229 + j*(-407) --151 + j*(263) --238 + j*(-291) -316 + j*(-284) -279 + j*(-5) -530 + j*(231) -362 + j*(-301) --351 + j*(88) --110 + j*(-561) -112 + j*(460) --511 + j*(-83) -465 + j*(-271) -302 + j*(-204) -164 + j*(355) --293 + j*(-134) -190 + j*(-144) -306 + j*(343) -368 + j*(298) -53 + j*(-6) --45 + j*(180) --273 + j*(359) --361 + j*(58) --361 + j*(-168) --212 + j*(-321) --178 + j*(13) -186 + j*(-363) --138 + j*(276) -149 + j*(-330) --303 + j*(291) -427 + j*(-233) -410 + j*(147) --484 + j*(243) -57 + j*(-330) -357 + j*(-601) -107 + j*(86) -402 + j*(-378) --295 + j*(-273) --211 + j*(-189) -264 + j*(360) -525 + j*(78) -414 + j*(161) --354 + j*(-292) -457 + j*(262) --247 + j*(284) -316 + j*(-690) -285 + j*(-289) -109 + j*(-199) --414 + j*(-325) --316 + j*(151) --11 + j*(278) -296 + j*(57) -403 + j*(187) -196 + j*(129) --380 + j*(-382) --358 + j*(432) -311 + j*(-158) --141 + j*(-752) --210 + j*(223) -181 + j*(-170) --144 + j*(479) -42 + j*(337) --118 + j*(-448) -222 + j*(-74) -631 + j*(-293) -339 + j*(-683) --165 + j*(141) -388 + j*(-554) --211 + j*(358) --309 + j*(110) --313 + j*(130) -223 + j*(560) -415 + j*(496) -11 + j*(344) -634 + j*(-202) -226 + j*(-28) --185 + j*(363) --289 + j*(107) -43 + j*(301) -91 + j*(-283) -76 + j*(-579) --298 + j*(95) -31 + j*(84) --288 + j*(252) -194 + j*(413) -264 + j*(-355) -165 + j*(-302) --120 + j*(101) -344 + j*(-684) --288 + j*(52) --290 + j*(-463) --135 + j*(286) --445 + j*(-125) --263 + j*(97) --277 + j*(-421) -302 + j*(-375) -455 + j*(412) --128 + j*(63) -118 + j*(107) --360 + j*(407) -54 + j*(366) --74 + j*(-502) -234 + j*(242) -572 + j*(-114) -197 + j*(-351) -518 + j*(128) -477 + j*(462) --64 + j*(393) --113 + j*(-435) -303 + j*(-301) --221 + j*(146) --116 + j*(-151) --352 + j*(-286) --298 + j*(-105) -153 + j*(-247) -539 + j*(7) -360 + j*(144) -110 + j*(74) -328 + j*(28) --337 + j*(424) -129 + j*(-260) -549 + j*(41) --368 + j*(378) --253 + j*(-668) -263 + j*(180) -253 + j*(-273) --412 + j*(212) --180 + j*(207) --329 + j*(-180) -154 + j*(-82) --102 + j*(197) --356 + j*(107) --89 + j*(-513) --393 + j*(41) -344 + j*(403) -245 + j*(286) --390 + j*(146) -184 + j*(-487) -132 + j*(-408) --330 + j*(441) --28 + j*(579) -197 + j*(-210) --52 + j*(-171) -317 + j*(201) --162 + j*(-148) -111 + j*(-285) --148 + j*(177) --291 + j*(210) --358 + j*(-169) -421 + j*(-378) --173 + j*(52) -19 + j*(-194) -211 + j*(62) --416 + j*(202) --296 + j*(194) --357 + j*(72) --214 + j*(49) -289 + j*(400) --182 + j*(349) --583 + j*(-578) --322 + j*(232) --136 + j*(179) -276 + j*(397) --436 + j*(24) --224 + j*(-35) -74 + j*(110) --414 + j*(-103) --369 + j*(513) --141 + j*(-160) -309 + j*(346) -276 + j*(763) --186 + j*(401) -137 + j*(202) -179 + j*(272) --358 + j*(217) -109 + j*(330) --497 + j*(70) --352 + j*(288) -957 + j*(428) -136 + j*(149) --426 + j*(-522) -91 + j*(52) --378 + j*(150) --367 + j*(416) -130 + j*(123) --260 + j*(361) --31 + j*(-247) -346 + j*(-375) -166 + j*(-52) -158 + j*(-178) --497 + j*(201) -376 + j*(-266) --416 + j*(258) --198 + j*(175) --107 + j*(-139) --255 + j*(77) --380 + j*(267) --342 + j*(277) --279 + j*(-194) -217 + j*(9) -65 + j*(-134) --23 + j*(-395) -195 + j*(262) -86 + j*(-10) --37 + j*(278) --40 + j*(-135) -6 + j*(-1) -144 + j*(163) --16 + j*(-21) --5 + j*(147) --47 + j*(-260) --321 + j*(172) -238 + j*(-30) -216 + j*(81) -11 + j*(-53) --47 + j*(-23) -93 + j*(-51) --1 + j*(-8) --76 + j*(-121) --240 + j*(0) --38 + j*(-183) -0 + j*(163) -234 + j*(-31) --15 + j*(244) -76 + j*(-4) --153 + j*(257) -173 + j*(26) --37 + j*(-276) --131 + j*(206) -65 + j*(192) -278 + j*(-243) --161 + j*(-1) -44 + j*(-173) -167 + j*(245) --102 + j*(122) --47 + j*(-253) --21 + j*(-165) --1 + j*(57) -10 + j*(-13) -48 + j*(188) --45 + j*(-52) --17 + j*(-233) -32 + j*(-101) --295 + j*(-116) -388 + j*(128) --134 + j*(-117) --81 + j*(-160) --45 + j*(-393) -72 + j*(-60) --24 + j*(-247) -208 + j*(-424) -280 + j*(-19) --87 + j*(276) -23 + j*(70) -88 + j*(-285) -1 + j*(-189) -121 + j*(-41) --55 + j*(-153) --192 + j*(147) -98 + j*(-22) -0 + j*(218) --347 + j*(138) --95 + j*(-165) -214 + j*(-88) --113 + j*(-315) --131 + j*(390) --264 + j*(144) -114 + j*(-233) --54 + j*(-50) --342 + j*(124) --173 + j*(-27) -140 + j*(-115) -48 + j*(361) --327 + j*(187) --40 + j*(-163) --104 + j*(229) -144 + j*(-105) --83 + j*(-214) -183 + j*(117) --150 + j*(75) -160 + j*(-52) --6 + j*(-65) -209 + j*(132) --195 + j*(275) -75 + j*(-323) --33 + j*(-221) -92 + j*(-206) -8 + j*(-38) --83 + j*(-167) -68 + j*(198) -31 + j*(13) --310 + j*(318) -105 + j*(175) -5 + j*(-67) -42 + j*(-11) -107 + j*(29) -79 + j*(-83) --68 + j*(-226) -366 + j*(92) --146 + j*(172) -74 + j*(386) -160 + j*(-37) -327 + j*(-145) --189 + j*(208) --25 + j*(-168) -93 + j*(-51) -15 + j*(202) -4 + j*(2) -37 + j*(152) --97 + j*(-64) -276 + j*(257) --67 + j*(-88) --58 + j*(-4) --297 + j*(242) --194 + j*(-285) --26 + j*(139) --220 + j*(271) -27 + j*(-36) --277 + j*(98) -182 + j*(-327) -314 + j*(211) --52 + j*(-117) --92 + j*(64) --197 + j*(-198) --291 + j*(16) -45 + j*(100) -7 + j*(-226) --6 + j*(-90) --440 + j*(110) --20 + j*(144) -296 + j*(-84) --49 + j*(29) --97 + j*(416) --202 + j*(-2) -31 + j*(-51) --156 + j*(-209) --198 + j*(-40) -66 + j*(82) --215 + j*(378) -414 + j*(23) --291 + j*(122) -221 + j*(-47) --374 + j*(33) -348 + j*(-216) -187 + j*(70) -129 + j*(-145) --108 + j*(-35) --100 + j*(-327) -228 + j*(-83) -334 + j*(107) --380 + j*(-332) --64 + j*(93) -177 + j*(-193) --50 + j*(-9) --325 + j*(152) --71 + j*(111) -291 + j*(-116) --158 + j*(229) --150 + j*(-164) -36 + j*(126) -8 + j*(-73) -190 + j*(-161) --25 + j*(-20) -130 + j*(99) -35 + j*(276) -242 + j*(171) --145 + j*(-106) -103 + j*(-179) -127 + j*(-1) --112 + j*(-151) --141 + j*(308) -199 + j*(-22) -23 + j*(156) --23 + j*(-225) --168 + j*(37) --245 + j*(83) -145 + j*(40) --308 + j*(-13) -39 + j*(7) -16 + j*(-214) -87 + j*(-40) --126 + j*(-33) -371 + j*(313) -80 + j*(-34) -8 + j*(175) --110 + j*(368) --66 + j*(130) -124 + j*(-55) --166 + j*(-139) -119 + j*(126) --124 + j*(245) --150 + j*(110) -161 + j*(-21) -52 + j*(-105) --98 + j*(27) --139 + j*(125) -38 + j*(76) --90 + j*(259) --3 + j*(23) -31 + j*(84) -292 + j*(-22) --146 + j*(505) -293 + j*(71) --9 + j*(198) -9 + j*(15) --60 + j*(-96) --231 + j*(241) --232 + j*(-240) -211 + j*(-120) --145 + j*(54) -3 + j*(16) --204 + j*(-413) --373 + j*(-87) --5 + j*(128) --222 + j*(-5) --42 + j*(-223) --224 + j*(33) --10 + j*(-8) --134 + j*(25) --187 + j*(351) -109 + j*(-105) -114 + j*(-36) --226 + j*(84) --168 + j*(-105) --91 + j*(-60) -55 + j*(-227) --25 + j*(-95) --35 + j*(325) -59 + j*(-122) -81 + j*(-134) --172 + j*(117) --4 + j*(141) -30 + j*(-124) --381 + j*(-111) --119 + j*(-175) -103 + j*(-36) --96 + j*(-64) -197 + j*(-59) -52 + j*(-100) --151 + j*(125) --132 + j*(-57) --35 + j*(-74) -52 + j*(-267) -139 + j*(4) --177 + j*(177) --141 + j*(-110) --64 + j*(372) --204 + j*(-33) -113 + j*(187) --123 + j*(91) -177 + j*(-75) -56 + j*(-164) --342 + j*(178) --83 + j*(124) -71 + j*(-26) --179 + j*(76) --7 + j*(-199) --92 + j*(94) -67 + j*(-88) -62 + j*(197) -144 + j*(223) --164 + j*(25) -148 + j*(-99) -176 + j*(-33) -96 + j*(-22) -4 + j*(-28) -8 + j*(-88) --38 + j*(69) -20 + j*(27) --151 + j*(-105) -46 + j*(279) --182 + j*(-129) -187 + j*(-45) -125 + j*(41) --105 + j*(260) -139 + j*(-175) -197 + j*(62) --47 + j*(-6) -8 + j*(-264) -145 + j*(-122) --71 + j*(-253) --63 + j*(233) -121 + j*(-4) --58 + j*(111) -358 + j*(151) --23 + j*(-28) -11 + j*(-8) -11 + j*(26) --92 + j*(-46) --100 + j*(336) --50 + j*(31) --165 + j*(-91) -116 + j*(-206) -65 + j*(272) --177 + j*(163) --134 + j*(44) -194 + j*(84) -214 + j*(-51) --225 + j*(210) -88 + j*(158) -120 + j*(-69) -111 + j*(115) -139 + j*(205) -329 + j*(-174) -47 + j*(82) --327 + j*(-317) -37 + j*(154) -84 + j*(14) -84 + j*(-11) -221 + j*(155) --364 + j*(194) -113 + j*(43) -4 + j*(21) --107 + j*(-91) --89 + j*(26) --249 + j*(-27) -23 + j*(132) -127 + j*(-84) --12 + j*(-115) --71 + j*(-11) --30 + j*(-1) --172 + j*(138) -335 + j*(131) --389 + j*(-301) --227 + j*(-21) -31 + j*(-216) --5 + j*(-132) --144 + j*(-299) --165 + j*(228) -3 + j*(-140) --32 + j*(64) --133 + j*(62) --59 + j*(-167) --209 + j*(-176) -313 + j*(-33) --28 + j*(137) -184 + j*(219) --16 + j*(294) --196 + j*(-70) --86 + j*(38) --75 + j*(-91) -356 + j*(226) --60 + j*(390) -22 + j*(-121) -90 + j*(76) --141 + j*(-10) -87 + j*(57) --245 + j*(-4) -88 + j*(-81) --40 + j*(148) --1 + j*(209) -216 + j*(24) -26 + j*(13) --249 + j*(45) -251 + j*(-110) --366 + j*(-232) -13 + j*(130) -17 + j*(271) --126 + j*(-201) --52 + j*(-122) -102 + j*(-264) -74 + j*(206) -317 + j*(-79) -122 + j*(13) -186 + j*(132) --86 + j*(-180) --253 + j*(-194) -86 + j*(-68) --88 + j*(-161) -159 + j*(-275) -146 + j*(-74) --85 + j*(-33) --16 + j*(-133) --136 + j*(-61) --112 + j*(-103) --156 + j*(57) -43 + j*(-80) -58 + j*(193) --187 + j*(-203) -197 + j*(191) -277 + j*(26) -4 + j*(-117) --81 + j*(182) --8 + j*(-11) -54 + j*(-61) --351 + j*(64) --178 + j*(-216) --4 + j*(-388) --141 + j*(91) --140 + j*(-93) -33 + j*(197) -63 + j*(-147) -17 + j*(132) -10 + j*(127) --253 + j*(192) --36 + j*(107) -125 + j*(-66) --131 + j*(-82) --250 + j*(-14) --285 + j*(5) -119 + j*(-23) -28 + j*(253) --49 + j*(330) -73 + j*(24) -82 + j*(40) -4 + j*(179) -44 + j*(-324) --77 + j*(64) --16 + j*(-161) -181 + j*(-55) --248 + j*(-226) --185 + j*(130) -108 + j*(110) --337 + j*(-95) -117 + j*(-192) --18 + j*(104) -185 + j*(204) --106 + j*(28) --400 + j*(57) --91 + j*(47) --243 + j*(-143) --141 + j*(37) -216 + j*(79) --63 + j*(23) -1 + j*(-54) --258 + j*(254) --26 + j*(-60) -203 + j*(132) -260 + j*(57) --13 + j*(209) -46 + j*(-156) -55 + j*(294) --322 + j*(-226) -101 + j*(118) -163 + j*(-56) -189 + j*(-47) -209 + j*(-12) -140 + j*(146) --81 + j*(282) --238 + j*(20) --152 + j*(180) --140 + j*(-190) -146 + j*(-109) --63 + j*(-105) -49 + j*(6) --37 + j*(-4) -25 + j*(-124) -21 + j*(-45) -214 + j*(209) -6 + j*(-68) --174 + j*(189) -79 + j*(-70) -103 + j*(167) --227 + j*(171) --139 + j*(-351) -245 + j*(-18) --17 + j*(325) --490 + j*(-99) -301 + j*(81) -218 + j*(-4) -32 + j*(-16) -274 + j*(-51) --122 + j*(21) -95 + j*(7) -295 + j*(-64) --18 + j*(245) --122 + j*(47) -86 + j*(7) -122 + j*(-269) -35 + j*(-125) -29 + j*(34) -187 + j*(53) --205 + j*(-129) --29 + j*(264) -93 + j*(-149) --36 + j*(-107) --225 + j*(255) -371 + j*(-177) --142 + j*(11) --230 + j*(217) --100 + j*(-18) -40 + j*(163) --57 + j*(-83) --293 + j*(316) --86 + j*(-52) -111 + j*(21) --91 + j*(-33) --121 + j*(-47) --133 + j*(-12) --7 + j*(124) --154 + j*(-30) --74 + j*(-225) -14 + j*(-54) --176 + j*(252) --217 + j*(-202) -65 + j*(-130) -144 + j*(192) -209 + j*(-108) -11 + j*(264) --10 + j*(-170) --9 + j*(-129) --90 + j*(-147) -108 + j*(44) --19 + j*(99) --256 + j*(53) -301 + j*(-249) --164 + j*(124) --231 + j*(-234) --64 + j*(-274) --40 + j*(28) -54 + j*(-162) -99 + j*(72) -78 + j*(135) --120 + j*(165) -123 + j*(-209) --23 + j*(306) --133 + j*(-216) --35 + j*(121) -260 + j*(264) -134 + j*(25) --32 + j*(255) --245 + j*(-106) --35 + j*(-74) -192 + j*(-317) --175 + j*(286) --25 + j*(-154) --146 + j*(29) -40 + j*(181) --10 + j*(119) --47 + j*(-151) -161 + j*(105) -205 + j*(-194) --270 + j*(28) --18 + j*(1) --131 + j*(125) -176 + j*(-149) -21 + j*(80) -13 + j*(-211) --273 + j*(123) --182 + j*(176) --247 + j*(87) -72 + j*(141) --78 + j*(-149) --96 + j*(158) --235 + j*(-231) --2 + j*(194) -44 + j*(192) --6 + j*(-80) -37 + j*(-110) --148 + j*(-328) --267 + j*(251) -168 + j*(175) -97 + j*(30) --54 + j*(-40) --168 + j*(89) --72 + j*(-33) --68 + j*(-249) --100 + j*(48) -64 + j*(-49) --161 + j*(150) -31 + j*(137) -27 + j*(-29) -243 + j*(28) --22 + j*(-22) -94 + j*(22) --238 + j*(-66) --6 + j*(-87) --109 + j*(99) -184 + j*(204) --250 + j*(-3) -263 + j*(-223) --428 + j*(-54) -155 + j*(-169) -43 + j*(-285) --182 + j*(-257) -71 + j*(-199) -37 + j*(-130) -51 + j*(41) --75 + j*(-66) --95 + j*(105) -33 + j*(-125) --195 + j*(-38) -281 + j*(-226) --16 + j*(-185) -85 + j*(64) --13 + j*(-259) -25 + j*(-330) -342 + j*(218) -91 + j*(331) --245 + j*(-42) --240 + j*(224) --66 + j*(-228) --37 + j*(182) -128 + j*(214) -109 + j*(129) --244 + j*(135) -237 + j*(178) --14 + j*(-62) --26 + j*(11) --275 + j*(-257) -99 + j*(-284) -97 + j*(501) --361 + j*(-166) --69 + j*(96) --25 + j*(-182) -227 + j*(94) -157 + j*(445) --29 + j*(-144) -368 + j*(-150) -40 + j*(-45) --46 + j*(143) -56 + j*(-343) --4 + j*(62) -272 + j*(-117) --291 + j*(83) --387 + j*(111) --93 + j*(-18) -250 + j*(-13) --193 + j*(48) -59 + j*(706) -264 + j*(228) -33 + j*(-315) -404 + j*(-147) --79 + j*(1) --296 + j*(-135) --250 + j*(-423) -36 + j*(27) -64 + j*(-75) --195 + j*(-198) --51 + j*(-132) --103 + j*(204) -261 + j*(-173) -44 + j*(-41) --77 + j*(55) --18 + j*(-163) --241 + j*(106) -76 + j*(-120) -346 + j*(323) --168 + j*(-142) -83 + j*(-60) -30 + j*(262) -250 + j*(-2) --146 + j*(-236) --66 + j*(-267) --28 + j*(-10) --58 + j*(-90) -139 + j*(-92) -143 + j*(105) --192 + j*(525) -119 + j*(158) -15 + j*(-111) -25 + j*(-11) --103 + j*(144) --283 + j*(-173) -356 + j*(-98) --53 + j*(274) --1 + j*(94) -204 + j*(91) -127 + j*(-239) --121 + j*(62) --2 + j*(145) -134 + j*(-30) --77 + j*(320) -148 + j*(27) --372 + j*(-130) -274 + j*(8) -71 + j*(-80) -333 + j*(-121) --292 + j*(-135) -205 + j*(479) --37 + j*(-227) -62 + j*(61) -83 + j*(-158) -279 + j*(-41) -31 + j*(132) --54 + j*(472) --214 + j*(261) -148 + j*(-199) -73 + j*(499) -78 + j*(-23) -108 + j*(-213) -25 + j*(-210) -12 + j*(315) --42 + j*(63) --86 + j*(119) -76 + j*(246) -211 + j*(-351) --42 + j*(-95) --47 + j*(156) -37 + j*(144) --249 + j*(-69) --274 + j*(-139) -110 + j*(-13) --269 + j*(21) -173 + j*(-42) -55 + j*(110) --130 + j*(-165) --187 + j*(-255) --53 + j*(-127) -262 + j*(-6) -16 + j*(28) --292 + j*(-63) --219 + j*(-310) --93 + j*(404) --34 + j*(60) -78 + j*(-91) --74 + j*(146) --162 + j*(-143) --127 + j*(64) -400 + j*(-46) --81 + j*(373) -408 + j*(-136) --45 + j*(13) --161 + j*(-119) -39 + j*(310) -50 + j*(-281) --64 + j*(4) -305 + j*(69) --59 + j*(45) --137 + j*(416) -56 + j*(-198) -273 + j*(-237) -141 + j*(173) -18 + j*(-60) --41 + j*(225) -236 + j*(297) -80 + j*(18) --388 + j*(277) -180 + j*(-110) --67 + j*(-74) --215 + j*(-148) -8 + j*(242) --293 + j*(-219) --88 + j*(81) -117 + j*(-18) -78 + j*(-66) --80 + j*(-532) -141 + j*(21) --211 + j*(-342) --204 + j*(-96) --131 + j*(-108) -124 + j*(-298) -43 + j*(-57) -13 + j*(220) -206 + j*(33) -43 + j*(-93) --8 + j*(-59) -300 + j*(-127) --181 + j*(218) -110 + j*(-66) -148 + j*(372) --188 + j*(66) -28 + j*(-363) --211 + j*(37) -110 + j*(22) --132 + j*(110) --122 + j*(-109) --124 + j*(241) --132 + j*(8) --109 + j*(-1) --186 + j*(-119) --202 + j*(-288) --29 + j*(143) -115 + j*(-307) --51 + j*(-297) --89 + j*(-169) -26 + j*(299) -66 + j*(76) --62 + j*(133) --110 + j*(-276) -410 + j*(-174) --315 + j*(-66) --5 + j*(165) -175 + j*(-115) --167 + j*(-226) --148 + j*(273) -197 + j*(-184) --124 + j*(159) -285 + j*(-25) -221 + j*(13) -102 + j*(-86) -56 + j*(183) --1 + j*(-25) -71 + j*(-21) --281 + j*(156) --62 + j*(40) --3 + j*(153) -159 + j*(323) --15 + j*(173) --105 + j*(-136) -1 + j*(25) -7 + j*(154) --380 + j*(-333) --211 + j*(293) -11 + j*(-76) --137 + j*(-161) -44 + j*(-180) -378 + j*(-2) -322 + j*(-284) -217 + j*(34) -107 + j*(161) --20 + j*(156) -36 + j*(-98) --142 + j*(11) -117 + j*(105) -51 + j*(-16) -253 + j*(-144) --33 + j*(-183) --190 + j*(-316) --55 + j*(207) --121 + j*(440) --301 + j*(-78) --73 + j*(-63) -95 + j*(-9) --110 + j*(196) -329 + j*(-70) --90 + j*(34) --246 + j*(177) --52 + j*(-62) -40 + j*(-156) -13 + j*(67) --311 + j*(129) -101 + j*(88) --107 + j*(107) --245 + j*(-196) --18 + j*(216) -126 + j*(161) --21 + j*(194) --64 + j*(-221) -40 + j*(-85) -107 + j*(168) -24 + j*(84) --122 + j*(15) --183 + j*(-73) -133 + j*(-38) --105 + j*(37) --154 + j*(35) -100 + j*(150) -500 + j*(-12) -115 + j*(4) -290 + j*(41) -243 + j*(-122) --17 + j*(-80) -49 + j*(-163) --144 + j*(-378) --375 + j*(-136) -35 + j*(-108) --19 + j*(-320) --138 + j*(-10) -169 + j*(-57) --212 + j*(114) -375 + j*(-63) --171 + j*(117) -205 + j*(-184) --233 + j*(77) -74 + j*(-168) --19 + j*(142) --77 + j*(124) --53 + j*(-18) -51 + j*(-360) --148 + j*(-2) -226 + j*(-23) -61 + j*(-165) --67 + j*(-58) -278 + j*(-44) -412 + j*(-89) --74 + j*(-80) --32 + j*(151) --106 + j*(226) -190 + j*(-121) --247 + j*(-198) -36 + j*(-45) --82 + j*(311) -115 + j*(1) --379 + j*(4) -172 + j*(38) --187 + j*(134) --156 + j*(-50) --126 + j*(-186) --20 + j*(-57) -312 + j*(-151) --218 + j*(180) --42 + j*(-283) --98 + j*(112) -145 + j*(57) -21 + j*(-140) -223 + j*(119) -71 + j*(-245) -134 + j*(243) --80 + j*(252) --33 + j*(-303) --5 + j*(84) --161 + j*(-120) --268 + j*(-303) --62 + j*(-187) --151 + j*(-25) -164 + j*(-359) --130 + j*(293) --35 + j*(-424) --359 + j*(368) -79 + j*(235) -344 + j*(-23) --98 + j*(-108) -157 + j*(221) --342 + j*(-91) -35 + j*(-46) --111 + j*(-6) -119 + j*(-21) --146 + j*(144) -167 + j*(36) --347 + j*(-155) -238 + j*(4) -37 + j*(249) --159 + j*(-104) --79 + j*(348) -58 + j*(199) --2 + j*(-211) -347 + j*(73) -28 + j*(-163) --150 + j*(143) --34 + j*(-91) --53 + j*(390) --163 + j*(135) --274 + j*(-153) -69 + j*(194) -131 + j*(-263) --412 + j*(177) --86 + j*(-347) -52 + j*(-134) -264 + j*(84) -91 + j*(161) --64 + j*(-158) --34 + j*(-561) --90 + j*(-67) --67 + j*(-100) -117 + j*(-13) -16 + j*(-20) -144 + j*(128) -378 + j*(86) -96 + j*(-165) --218 + j*(-17) -78 + j*(281) -221 + j*(-293) -161 + j*(257) -170 + j*(98) --197 + j*(82) --374 + j*(211) -331 + j*(-194) -166 + j*(-191) -233 + j*(-141) -21 + j*(-85) --260 + j*(20) --378 + j*(212) -54 + j*(337) -217 + j*(342) -85 + j*(87) --145 + j*(105) -310 + j*(152) --69 + j*(137) -138 + j*(-73) --54 + j*(-25) --87 + j*(-16) -133 + j*(-134) -137 + j*(-126) -133 + j*(34) --137 + j*(7) -325 + j*(0) --141 + j*(185) -89 + j*(-3) --195 + j*(-91) -137 + j*(121) --211 + j*(-122) --57 + j*(88) --246 + j*(-217) -130 + j*(-260) --226 + j*(-54) --120 + j*(-135) -332 + j*(-94) --28 + j*(-57) -274 + j*(91) -49 + j*(-37) -173 + j*(119) -141 + j*(46) --79 + j*(-44) -95 + j*(-190) --48 + j*(-25) --94 + j*(-227) --261 + j*(-165) --60 + j*(87) --52 + j*(93) --146 + j*(-202) -24 + j*(-27) -110 + j*(-47) --88 + j*(-157) --37 + j*(305) --108 + j*(11) --304 + j*(-94) -0 + j*(86) -308 + j*(91) --243 + j*(121) -156 + j*(-95) -59 + j*(-81) --126 + j*(138) -177 + j*(32) --28 + j*(-145) -140 + j*(306) -44 + j*(-207) -4 + j*(-25) -69 + j*(91) --279 + j*(-240) --209 + j*(-70) --236 + j*(-49) --266 + j*(119) --29 + j*(40) -246 + j*(-281) --91 + j*(170) --66 + j*(-84) -257 + j*(-77) -169 + j*(205) --49 + j*(-64) -129 + j*(235) -153 + j*(-272) -25 + j*(167) -45 + j*(-199) -160 + j*(-20) --114 + j*(139) --255 + j*(-46) -276 + j*(-267) -145 + j*(72) -52 + j*(-160) --346 + j*(13) --107 + j*(203) --278 + j*(286) --279 + j*(300) --83 + j*(-110) -40 + j*(69) -77 + j*(-233) -177 + j*(55) -135 + j*(-241) -25 + j*(30) -100 + j*(81) -293 + j*(-232) --99 + j*(206) --428 + j*(232) -135 + j*(-12) -227 + j*(-14) -64 + j*(-328) -45 + j*(-37) --197 + j*(-253) -126 + j*(103) -113 + j*(4) --6 + j*(-86) -11 + j*(130) -45 + j*(-115) -3 + j*(141) --295 + j*(228) --132 + j*(-34) -328 + j*(7) --10 + j*(-414) -174 + j*(145) -108 + j*(-86) --244 + j*(10) --16 + j*(-123) --77 + j*(-84) -98 + j*(-405) -131 + j*(-130) --358 + j*(276) --59 + j*(-46) --523 + j*(75) --109 + j*(-81) --3 + j*(47) -197 + j*(207) -180 + j*(-38) -286 + j*(20) --299 + j*(-468) -107 + j*(-59) --273 + j*(-121) --14 + j*(-8) --58 + j*(-18) -123 + j*(266) -82 + j*(91) --117 + j*(70) -328 + j*(213) -165 + j*(-51) -234 + j*(-64) -192 + j*(-102) -25 + j*(81) --20 + j*(30) -54 + j*(-132) --57 + j*(91) -6 + j*(101) --6 + j*(66) -101 + j*(-100) -95 + j*(49) -160 + j*(272) -173 + j*(-262) -134 + j*(106) --59 + j*(9) -287 + j*(259) --105 + j*(-248) --156 + j*(-380) --287 + j*(141) --98 + j*(-66) -16 + j*(52) -63 + j*(103) -35 + j*(128) --104 + j*(-173) -86 + j*(226) -33 + j*(92) -149 + j*(49) -77 + j*(-76) --126 + j*(23) --417 + j*(13) --241 + j*(152) --30 + j*(-218) --176 + j*(-159) -93 + j*(105) -150 + j*(79) -163 + j*(66) -209 + j*(27) -21 + j*(-233) --144 + j*(16) -130 + j*(16) -322 + j*(192) --192 + j*(50) -230 + j*(-177) -98 + j*(-100) --127 + j*(-187) --153 + j*(33) -246 + j*(-37) -147 + j*(-141) --211 + j*(202) -265 + j*(177) -137 + j*(43) -538 + j*(218) --583 + j*(125) -52 + j*(42) -165 + j*(-288) --336 + j*(368) -175 + j*(-170) --441 + j*(240) -149 + j*(129) --235 + j*(148) --38 + j*(-30) --76 + j*(-467) -213 + j*(-158) -16 + j*(-30) --51 + j*(-43) --37 + j*(202) -16 + j*(-47) -199 + j*(-107) --161 + j*(105) --114 + j*(175) --57 + j*(-124) -13 + j*(-55) -148 + j*(-185) --76 + j*(-110) --127 + j*(95) -629 + j*(323) -75 + j*(-234) --103 + j*(-122) -88 + j*(-91) --88 + j*(-165) --19 + j*(47) --55 + j*(197) --31 + j*(-1) --206 + j*(52) --128 + j*(108) -218 + j*(58) --254 + j*(-185) --171 + j*(-105) -54 + j*(161) -31 + j*(41) --173 + j*(210) --4 + j*(45) --276 + j*(33) --270 + j*(92) -136 + j*(-105) -71 + j*(-156) -21 + j*(298) --134 + j*(284) -138 + j*(8) --62 + j*(483) --495 + j*(62) --231 + j*(-243) --231 + j*(139) -117 + j*(56) --121 + j*(-21) --205 + j*(-68) -46 + j*(-148) -272 + j*(-71) -22 + j*(-134) --88 + j*(170) -227 + j*(-7) -194 + j*(-216) --105 + j*(-83) -35 + j*(-38) --62 + j*(-11) --25 + j*(-57) --165 + j*(334) -59 + j*(-33) --66 + j*(54) -40 + j*(-2) --113 + j*(87) -61 + j*(-245) -47 + j*(-117) -71 + j*(-265) -177 + j*(298) -28 + j*(-226) -255 + j*(-117) -91 + j*(-88) --136 + j*(-4) -122 + j*(162) --66 + j*(156) --35 + j*(190) -112 + j*(233) -37 + j*(-218) --210 + j*(136) --117 + j*(199) --121 + j*(21) -21 + j*(42) --133 + j*(-1) -261 + j*(67) -274 + j*(-211) -117 + j*(109) --59 + j*(-67) --262 + j*(-350) -49 + j*(29) --164 + j*(-71) --7 + j*(148) --145 + j*(-25) -110 + j*(66) --63 + j*(-243) -45 + j*(371) -70 + j*(111) --69 + j*(-186) -170 + j*(-42) -7 + j*(18) --207 + j*(-57) -52 + j*(-413) -198 + j*(303) -42 + j*(-6) -162 + j*(131) --103 + j*(-41) --161 + j*(75) --18 + j*(137) -63 + j*(192) -317 + j*(201) --246 + j*(-300) -81 + j*(194) -410 + j*(-223) -168 + j*(109) --35 + j*(-319) --192 + j*(-197) --59 + j*(293) --138 + j*(-165) --124 + j*(-127) -161 + j*(-1) --225 + j*(252) -1 + j*(6) -66 + j*(-69) --95 + j*(33) -33 + j*(-151) --37 + j*(332) -38 + j*(-76) -113 + j*(-186) --132 + j*(-240) --67 + j*(125) --87 + j*(-121) --51 + j*(11) -436 + j*(-5) -5 + j*(4) -319 + j*(-137) -26 + j*(-105) --58 + j*(251) -49 + j*(-78) --159 + j*(-67) -82 + j*(177) --57 + j*(-229) -150 + j*(54) -39 + j*(-21) -23 + j*(-116) -83 + j*(154) --116 + j*(-146) -35 + j*(35) -129 + j*(66) --139 + j*(-21) --247 + j*(-43) -66 + j*(201) --48 + j*(-122) -115 + j*(-10) -59 + j*(-78) --135 + j*(325) -186 + j*(94) -321 + j*(64) --243 + j*(-163) --21 + j*(219) -92 + j*(18) --138 + j*(-308) -116 + j*(-98) --293 + j*(-9) --483 + j*(-84) --51 + j*(99) --34 + j*(-354) -44 + j*(124) --294 + j*(-137) --216 + j*(-135) -122 + j*(-151) --213 + j*(-472) --165 + j*(134) -184 + j*(-23) --178 + j*(-216) -71 + j*(-120) -35 + j*(107) --88 + j*(115) -394 + j*(-350) -261 + j*(-11) -18 + j*(69) -94 + j*(-419) -57 + j*(-196) --62 + j*(-337) --86 + j*(-111) --284 + j*(-116) --260 + j*(-87) --50 + j*(-44) -266 + j*(117) -37 + j*(-122) --249 + j*(80) -59 + j*(108) -151 + j*(-60) --13 + j*(60) -44 + j*(18) -233 + j*(108) -305 + j*(-136) --246 + j*(-6) --122 + j*(-25) --132 + j*(-170) --2 + j*(34) -93 + j*(-3) --87 + j*(93) -190 + j*(16) -192 + j*(314) -122 + j*(184) -185 + j*(272) --151 + j*(-226) -58 + j*(181) --39 + j*(-141) --36 + j*(-188) --96 + j*(158) --15 + j*(-67) --89 + j*(-180) -225 + j*(-103) -233 + j*(-173) -169 + j*(-23) --7 + j*(-106) -165 + j*(-170) --112 + j*(-73) --428 + j*(-307) --46 + j*(458) -235 + j*(-32) -255 + j*(268) -117 + j*(-291) -45 + j*(99) --194 + j*(-226) -103 + j*(-133) -107 + j*(-172) --18 + j*(-30) --3 + j*(-140) --146 + j*(-248) -127 + j*(12) --25 + j*(158) -199 + j*(170) -334 + j*(103) -38 + j*(218) --57 + j*(270) --229 + j*(6) --359 + j*(288) -100 + j*(107) -168 + j*(-62) -127 + j*(-205) --25 + j*(-194) -60 + j*(-344) --257 + j*(-204) -205 + j*(47) -63 + j*(6) -286 + j*(-307) -190 + j*(46) --404 + j*(24) -117 + j*(74) -17 + j*(-186) --358 + j*(70) --447 + j*(50) -317 + j*(-105) --300 + j*(-24) --170 + j*(-203) --18 + j*(-217) -401 + j*(59) --368 + j*(74) -227 + j*(-190) -150 + j*(6) -431 + j*(-158) -251 + j*(-187) --59 + j*(-158) --281 + j*(-172) --202 + j*(-277) -226 + j*(-39) --74 + j*(-202) -32 + j*(257) --249 + j*(-104) --342 + j*(18) --42 + j*(276) -20 + j*(-174) --58 + j*(55) -107 + j*(13) -62 + j*(110) --88 + j*(-8) --53 + j*(105) --98 + j*(-82) -40 + j*(-269) --168 + j*(146) --91 + j*(-114) --34 + j*(-367) --131 + j*(29) --137 + j*(58) --79 + j*(-44) --255 + j*(-166) --56 + j*(-137) --202 + j*(-279) -63 + j*(21) -383 + j*(-27) -19 + j*(252) -28 + j*(-19) --69 + j*(16) --136 + j*(275) -395 + j*(-137) -107 + j*(351) --59 + j*(279) --196 + j*(-284) -165 + j*(45) -68 + j*(-99) -404 + j*(303) --238 + j*(-18) -245 + j*(-265) -59 + j*(303) --35 + j*(-162) --453 + j*(-248) --334 + j*(163) --344 + j*(474) -6 + j*(-3) --201 + j*(269) -134 + j*(-625) -441 + j*(165) -89 + j*(-500) -170 + j*(475) -499 + j*(38) --637 + j*(-19) --191 + j*(444) --91 + j*(369) -129 + j*(270) -103 + j*(112) --11 + j*(255) -452 + j*(323) --325 + j*(-290) -485 + j*(-310) -238 + j*(-470) --148 + j*(-462) --323 + j*(-13) -175 + j*(-445) -381 + j*(-290) --479 + j*(-116) --348 + j*(245) -274 + j*(356) -54 + j*(233) -29 + j*(-153) -556 + j*(420) -88 + j*(27) --383 + j*(83) --45 + j*(606) -44 + j*(245) --272 + j*(-347) --452 + j*(-182) -35 + j*(165) -179 + j*(-366) --275 + j*(280) -294 + j*(-340) --371 + j*(200) --260 + j*(410) -210 + j*(-378) --54 + j*(371) -276 + j*(352) -524 + j*(361) -228 + j*(-63) --296 + j*(-247) -590 + j*(-115) --23 + j*(234) -71 + j*(255) --517 + j*(-235) -75 + j*(450) -89 + j*(-307) -180 + j*(313) -247 + j*(448) -197 + j*(98) -163 + j*(160) --272 + j*(182) -177 + j*(35) --397 + j*(201) --122 + j*(-438) --453 + j*(-634) --269 + j*(-228) --167 + j*(-662) -262 + j*(-260) -95 + j*(225) -477 + j*(356) --121 + j*(216) -77 + j*(161) --372 + j*(-286) --375 + j*(-124) --553 + j*(269) --320 + j*(-297) -158 + j*(-262) -456 + j*(-231) --440 + j*(-190) --234 + j*(182) -47 + j*(269) -122 + j*(54) --106 + j*(409) --245 + j*(228) --1 + j*(196) --120 + j*(-257) --173 + j*(80) --477 + j*(-206) -83 + j*(472) --611 + j*(176) -47 + j*(239) --474 + j*(89) -606 + j*(251) --338 + j*(451) -176 + j*(-199) --354 + j*(-397) --89 + j*(-178) -124 + j*(-152) -172 + j*(199) --367 + j*(-373) -461 + j*(-211) -341 + j*(63) -8 + j*(172) --398 + j*(109) -6 + j*(132) -422 + j*(139) --229 + j*(-193) --118 + j*(163) --74 + j*(105) --80 + j*(199) -622 + j*(-87) -206 + j*(-106) -62 + j*(117) --354 + j*(235) --129 + j*(-91) -413 + j*(430) --419 + j*(107) -236 + j*(187) --494 + j*(-507) --118 + j*(340) --25 + j*(335) -528 + j*(-308) --499 + j*(-47) --11 + j*(95) --275 + j*(259) --395 + j*(128) -35 + j*(264) --16 + j*(-187) -127 + j*(-355) -358 + j*(323) -517 + j*(13) --177 + j*(7) --335 + j*(-337) --570 + j*(210) -290 + j*(183) --529 + j*(-514) --87 + j*(272) --121 + j*(298) --682 + j*(-194) --99 + j*(228) --216 + j*(-336) -433 + j*(-46) --585 + j*(-307) --225 + j*(136) --92 + j*(-79) --38 + j*(413) --22 + j*(201) -272 + j*(311) -258 + j*(67) -19 + j*(-434) -417 + j*(343) --291 + j*(145) --197 + j*(173) -539 + j*(430) --530 + j*(-280) --69 + j*(276) --442 + j*(71) --363 + j*(-136) --390 + j*(245) --186 + j*(326) -426 + j*(217) -83 + j*(467) --613 + j*(281) -146 + j*(-255) -37 + j*(-203) --504 + j*(49) --48 + j*(-541) -165 + j*(33) --302 + j*(296) --528 + j*(73) --281 + j*(-112) -455 + j*(547) -245 + j*(-219) --552 + j*(-479) --163 + j*(-419) -235 + j*(424) --527 + j*(240) -25 + j*(-750) --203 + j*(-203) --205 + j*(-281) --88 + j*(88) -353 + j*(597) -362 + j*(287) --308 + j*(175) -569 + j*(180) -421 + j*(-441) --382 + j*(76) --40 + j*(180) --81 + j*(235) --308 + j*(169) -364 + j*(-674) --218 + j*(49) -437 + j*(369) -251 + j*(-216) -395 + j*(-381) --255 + j*(113) --411 + j*(300) --109 + j*(83) --132 + j*(512) -194 + j*(336) --83 + j*(283) -340 + j*(-88) -47 + j*(156) --71 + j*(293) -467 + j*(389) -269 + j*(-11) --188 + j*(-217) --266 + j*(220) --368 + j*(402) --394 + j*(153) --148 + j*(-221) -132 + j*(-19) -284 + j*(-238) --255 + j*(-104) --399 + j*(-474) --693 + j*(211) --318 + j*(97) --568 + j*(-313) -206 + j*(10) -339 + j*(-526) --535 + j*(-288) --4 + j*(-254) -537 + j*(140) --313 + j*(377) -59 + j*(164) -257 + j*(258) -387 + j*(-396) -252 + j*(650) -144 + j*(-562) --56 + j*(-597) --163 + j*(377) --89 + j*(488) --245 + j*(-170) --94 + j*(-573) --248 + j*(374) -327 + j*(-499) --438 + j*(89) -228 + j*(-331) -40 + j*(-243) -205 + j*(320) --280 + j*(-1) -380 + j*(-342) --539 + j*(176) -37 + j*(-398) --567 + j*(474) --322 + j*(319) -118 + j*(222) --317 + j*(-47) -304 + j*(-267) -355 + j*(-300) -146 + j*(256) --330 + j*(-215) -23 + j*(435) -354 + j*(83) -231 + j*(90) -152 + j*(-227) --246 + j*(262) --451 + j*(341) --208 + j*(-239) -256 + j*(-187) --474 + j*(-392) -293 + j*(-143) -397 + j*(273) -349 + j*(150) -211 + j*(62) --249 + j*(-354) -76 + j*(213) --129 + j*(-209) --555 + j*(-134) -264 + j*(-363) -457 + j*(-358) --165 + j*(-33) -149 + j*(-256) -190 + j*(136) -182 + j*(190) -371 + j*(287) -252 + j*(56) -395 + j*(391) -308 + j*(-521) -45 + j*(-256) --9 + j*(-543) -323 + j*(407) -486 + j*(-177) --363 + j*(29) -206 + j*(-639) --333 + j*(-112) -71 + j*(-152) -21 + j*(-375) -154 + j*(39) --103 + j*(-450) --281 + j*(-57) --215 + j*(428) --332 + j*(-16) -349 + j*(-7) --145 + j*(-528) -226 + j*(295) -472 + j*(-151) -56 + j*(241) -144 + j*(75) --641 + j*(-214) -316 + j*(303) --523 + j*(-491) -504 + j*(373) -170 + j*(419) --469 + j*(-817) -76 + j*(163) -204 + j*(-40) --467 + j*(-346) --181 + j*(93) --25 + j*(-513) -204 + j*(446) -525 + j*(229) --499 + j*(383) --91 + j*(288) -33 + j*(-115) -8 + j*(-433) --238 + j*(-446) -156 + j*(496) -207 + j*(17) --271 + j*(-318) -287 + j*(-330) --212 + j*(-262) --62 + j*(-20) -617 + j*(157) --40 + j*(-72) --256 + j*(-126) -313 + j*(-422) --209 + j*(23) -433 + j*(-441) -175 + j*(-378) --223 + j*(16) --1 + j*(-623) -441 + j*(-211) --243 + j*(-511) --370 + j*(-292) --114 + j*(-321) --347 + j*(-197) --501 + j*(-327) -57 + j*(-296) --231 + j*(241) -148 + j*(68) --516 + j*(391) -250 + j*(-153) --300 + j*(-183) --9 + j*(-402) -332 + j*(197) -209 + j*(280) -115 + j*(-447) --167 + j*(66) -455 + j*(105) -307 + j*(98) -409 + j*(-368) -37 + j*(-124) -137 + j*(238) --402 + j*(-307) --319 + j*(-198) -37 + j*(-339) -223 + j*(199) --354 + j*(-160) --3 + j*(401) --11 + j*(30) -377 + j*(-197) --639 + j*(-83) --15 + j*(296) -79 + j*(-421) --197 + j*(-234) --47 + j*(-387) -629 + j*(30) -293 + j*(170) -595 + j*(486) --391 + j*(256) --44 + j*(25) --497 + j*(364) --74 + j*(198) -127 + j*(322) --373 + j*(161) --200 + j*(67) -503 + j*(301) -319 + j*(209) -276 + j*(-260) --539 + j*(-240) --53 + j*(356) -340 + j*(-97) -28 + j*(321) -45 + j*(-135) -1 + j*(-404) -319 + j*(-499) -457 + j*(-78) -178 + j*(-281) --399 + j*(-112) -124 + j*(-13) --195 + j*(-286) -132 + j*(354) -677 + j*(-21) --69 + j*(-286) -571 + j*(197) -141 + j*(17) -126 + j*(282) -176 + j*(611) -419 + j*(-260) -202 + j*(-305) -196 + j*(-390) --696 + j*(547) -226 + j*(-73) -187 + j*(537) --245 + j*(276) --508 + j*(139) -364 + j*(235) -438 + j*(-310) -284 + j*(-198) --246 + j*(616) -346 + j*(-528) -190 + j*(365) -279 + j*(310) --286 + j*(287) --128 + j*(-385) --150 + j*(461) -305 + j*(81) --167 + j*(305) -177 + j*(310) --1 + j*(-93) --322 + j*(450) --278 + j*(-342) -549 + j*(328) --168 + j*(540) -351 + j*(-178) -217 + j*(314) --275 + j*(300) -163 + j*(-137) --153 + j*(-810) --314 + j*(457) -279 + j*(-263) -157 + j*(-163) -622 + j*(-212) -70 + j*(-303) -275 + j*(-532) -321 + j*(409) -134 + j*(293) --91 + j*(-387) -272 + j*(127) --312 + j*(-547) --226 + j*(-198) --518 + j*(583) -117 + j*(218) -658 + j*(19) -317 + j*(691) --420 + j*(193) -62 + j*(-383) --79 + j*(-174) -74 + j*(348) -354 + j*(-148) --478 + j*(-88) -393 + j*(-581) -282 + j*(16) -214 + j*(416) --163 + j*(-387) -226 + j*(-209) -44 + j*(-400) -345 + j*(-215) --203 + j*(-110) -269 + j*(301) --269 + j*(75) -199 + j*(471) --320 + j*(1) --648 + j*(-421) -245 + j*(-436) --57 + j*(183) --571 + j*(21) --403 + j*(158) -427 + j*(218) --327 + j*(-246) -529 + j*(459) -150 + j*(127) --418 + j*(-54) -412 + j*(369) -116 + j*(-91) -395 + j*(296) -301 + j*(276) -566 + j*(285) -15 + j*(-486) -267 + j*(511) --98 + j*(-312) --190 + j*(-24) --30 + j*(-380) --484 + j*(-349) --109 + j*(85) --43 + j*(-262) -320 + j*(355) --552 + j*(-317) --95 + j*(250) -358 + j*(277) --62 + j*(-587) -128 + j*(-55) --302 + j*(127) --338 + j*(-502) --90 + j*(-230) --271 + j*(-47) -638 + j*(-255) -330 + j*(-83) --233 + j*(421) --182 + j*(-139) --32 + j*(405) -296 + j*(157) -28 + j*(216) -129 + j*(1) --267 + j*(-117) --310 + j*(-152) --390 + j*(-285) -389 + j*(371) -199 + j*(165) -120 + j*(45) -530 + j*(354) --42 + j*(-301) -368 + j*(-213) --28 + j*(-317) --89 + j*(-516) --32 + j*(213) -218 + j*(105) --168 + j*(293) --261 + j*(225) -158 + j*(221) --180 + j*(-234) -236 + j*(383) --63 + j*(-86) -319 + j*(-243) -265 + j*(60) --63 + j*(149) -191 + j*(-45) --172 + j*(202) --212 + j*(616) --405 + j*(387) --325 + j*(19) --18 + j*(149) --594 + j*(-148) --387 + j*(460) --368 + j*(469) -407 + j*(310) --475 + j*(6) --474 + j*(30) --553 + j*(331) --99 + j*(-116) -265 + j*(-308) -188 + j*(-201) -64 + j*(-253) --30 + j*(-274) --364 + j*(322) -309 + j*(-317) --293 + j*(223) -197 + j*(-407) -433 + j*(-237) --73 + j*(37) -392 + j*(373) --235 + j*(-14) -425 + j*(-168) --192 + j*(49) -15 + j*(-447) -61 + j*(202) -374 + j*(-368) -393 + j*(-243) -383 + j*(-417) -214 + j*(-48) --228 + j*(148) --298 + j*(-249) -55 + j*(-243) -269 + j*(-70) -230 + j*(85) -402 + j*(-211) --491 + j*(-202) --465 + j*(-66) -556 + j*(352) -105 + j*(473) -358 + j*(-113) --377 + j*(244) --344 + j*(-247) --160 + j*(233) -437 + j*(-361) -288 + j*(184) -94 + j*(-404) --11 + j*(205) --216 + j*(-250) --11 + j*(-221) --1 + j*(-287) -269 + j*(-443) -244 + j*(-533) --298 + j*(-8) --180 + j*(109) -248 + j*(479) -213 + j*(124) -358 + j*(541) --181 + j*(-170) --250 + j*(187) -117 + j*(-116) --319 + j*(226) -206 + j*(124) --320 + j*(-134) -241 + j*(518) --218 + j*(6) --407 + j*(-465) -93 + j*(479) --550 + j*(275) -112 + j*(623) --153 + j*(102) --38 + j*(-216) -125 + j*(-53) -243 + j*(-223) --298 + j*(-80) -358 + j*(153) --172 + j*(99) --166 + j*(-334) --24 + j*(136) --269 + j*(83) --16 + j*(141) --81 + j*(-37) -288 + j*(-160) -76 + j*(-252) -15 + j*(-38) -52 + j*(-147) --139 + j*(-18) --134 + j*(163) --214 + j*(-61) --187 + j*(259) -317 + j*(-68) --102 + j*(-43) --310 + j*(-237) -28 + j*(-4) --106 + j*(21) -106 + j*(-231) --339 + j*(50) -30 + j*(-218) --42 + j*(-162) --235 + j*(-288) --110 + j*(-78) -95 + j*(413) --305 + j*(67) -238 + j*(279) -124 + j*(196) --105 + j*(-66) --495 + j*(-67) -190 + j*(62) --241 + j*(-206) -99 + j*(3) --175 + j*(-147) -78 + j*(-20) --103 + j*(-211) --167 + j*(-285) -54 + j*(-207) -88 + j*(11) -21 + j*(35) --62 + j*(13) -317 + j*(199) -113 + j*(122) --373 + j*(252) -94 + j*(-60) -35 + j*(117) --180 + j*(194) --21 + j*(81) -21 + j*(87) --96 + j*(-382) --185 + j*(100) --463 + j*(392) --78 + j*(-193) -312 + j*(-53) --126 + j*(-49) -217 + j*(52) --62 + j*(187) --66 + j*(76) --37 + j*(-108) -82 + j*(-197) -37 + j*(-62) -45 + j*(-120) -83 + j*(-103) --91 + j*(165) --77 + j*(90) --224 + j*(160) --145 + j*(67) -230 + j*(-203) -143 + j*(54) -223 + j*(163) -42 + j*(-2) -39 + j*(-60) -2 + j*(235) -216 + j*(274) -34 + j*(-177) -138 + j*(-175) --220 + j*(-211) --15 + j*(36) --23 + j*(300) -91 + j*(282) --3 + j*(166) --193 + j*(-123) --103 + j*(27) --5 + j*(28) --121 + j*(60) -243 + j*(-2) -145 + j*(-293) --127 + j*(415) --83 + j*(267) --95 + j*(47) -35 + j*(96) --53 + j*(-190) -18 + j*(-146) --76 + j*(165) -131 + j*(-103) -5 + j*(-44) -57 + j*(-155) --339 + j*(-77) -8 + j*(-175) -157 + j*(16) -119 + j*(149) --276 + j*(-163) -23 + j*(107) -69 + j*(-146) -135 + j*(-267) -94 + j*(103) -27 + j*(57) -29 + j*(164) -24 + j*(-66) --98 + j*(-193) --9 + j*(51) --144 + j*(-103) -346 + j*(59) -377 + j*(262) -82 + j*(-277) -60 + j*(143) -88 + j*(107) -192 + j*(-120) --146 + j*(-35) --455 + j*(107) -91 + j*(236) -181 + j*(45) -90 + j*(64) --56 + j*(-392) --73 + j*(-43) -99 + j*(9) --270 + j*(-105) --62 + j*(-435) --349 + j*(-218) --298 + j*(-86) --137 + j*(-90) -76 + j*(28) -235 + j*(-12) --63 + j*(-119) --180 + j*(71) --165 + j*(218) --96 + j*(-2) -1 + j*(-390) --1 + j*(5) -59 + j*(-162) -33 + j*(171) -9 + j*(-5) -387 + j*(-101) --89 + j*(94) --168 + j*(-165) --230 + j*(-2) -446 + j*(198) -209 + j*(161) -172 + j*(153) -34 + j*(153) -80 + j*(3) --238 + j*(245) --28 + j*(-286) -261 + j*(202) --277 + j*(139) -76 + j*(148) -321 + j*(-148) -5 + j*(-124) -175 + j*(286) --22 + j*(95) -14 + j*(-212) --30 + j*(-224) --52 + j*(-112) -240 + j*(-124) --21 + j*(292) --39 + j*(-235) -81 + j*(262) -3 + j*(-186) -74 + j*(-12) -178 + j*(84) -86 + j*(-62) -238 + j*(-4) -4 + j*(13) -265 + j*(-82) -37 + j*(218) --187 + j*(71) --288 + j*(330) --112 + j*(340) -71 + j*(-57) --62 + j*(81) -18 + j*(96) --84 + j*(132) -10 + j*(162) -97 + j*(4) -50 + j*(308) --25 + j*(442) --136 + j*(187) --161 + j*(109) --50 + j*(54) -210 + j*(-192) -59 + j*(174) --51 + j*(-252) -139 + j*(-155) -280 + j*(156) -32 + j*(-54) -211 + j*(24) --198 + j*(-298) -165 + j*(206) -122 + j*(-144) -30 + j*(119) --21 + j*(281) -74 + j*(-119) --54 + j*(-23) --25 + j*(332) -78 + j*(-199) --125 + j*(-74) -232 + j*(11) --199 + j*(154) -311 + j*(31) -76 + j*(307) -39 + j*(-23) --165 + j*(397) -310 + j*(42) -255 + j*(-36) -276 + j*(-68) --192 + j*(20) --98 + j*(166) -3 + j*(-489) -41 + j*(177) --72 + j*(305) --52 + j*(-67) -66 + j*(-297) -20 + j*(-185) --270 + j*(-66) -15 + j*(-18) --71 + j*(-7) -40 + j*(-203) -199 + j*(-431) -316 + j*(-88) -46 + j*(90) --196 + j*(38) -91 + j*(-21) --1 + j*(169) -96 + j*(36) --76 + j*(-205) -289 + j*(76) --132 + j*(-141) --145 + j*(-97) --1 + j*(171) --51 + j*(182) -19 + j*(-129) -40 + j*(50) --175 + j*(-300) -21 + j*(74) -51 + j*(142) --128 + j*(-64) --43 + j*(-92) -247 + j*(109) --53 + j*(-28) --20 + j*(-168) -47 + j*(331) -8 + j*(-158) --7 + j*(-202) --51 + j*(-9) -49 + j*(66) -26 + j*(67) --157 + j*(-441) -82 + j*(-47) --124 + j*(165) --134 + j*(201) --74 + j*(184) -201 + j*(-29) -85 + j*(-272) -68 + j*(-132) -138 + j*(-243) --44 + j*(170) --154 + j*(-1) --93 + j*(79) -132 + j*(-134) --168 + j*(132) -147 + j*(144) --113 + j*(-10) -88 + j*(124) --267 + j*(25) -63 + j*(-53) -156 + j*(-330) -75 + j*(167) -238 + j*(0) -189 + j*(29) --175 + j*(-159) -110 + j*(-90) --68 + j*(-70) -36 + j*(-15) -6 + j*(-356) -138 + j*(315) -17 + j*(-114) --239 + j*(129) -279 + j*(21) --151 + j*(-25) -103 + j*(-17) -213 + j*(8) --81 + j*(148) --171 + j*(24) --63 + j*(6) -178 + j*(-13) -115 + j*(115) -187 + j*(148) --191 + j*(-442) --9 + j*(218) --60 + j*(101) --64 + j*(191) --21 + j*(-170) -78 + j*(110) --395 + j*(216) -122 + j*(186) --81 + j*(2) --324 + j*(237) -26 + j*(-274) -60 + j*(-154) --54 + j*(-83) -9 + j*(240) --117 + j*(63) --10 + j*(3) -109 + j*(124) -55 + j*(-28) -51 + j*(-1) -293 + j*(-194) --88 + j*(-208) --58 + j*(-27) -48 + j*(117) --287 + j*(97) --105 + j*(-250) --2 + j*(-269) --204 + j*(-248) --189 + j*(-123) --134 + j*(206) --114 + j*(-123) --180 + j*(-58) --320 + j*(-144) --265 + j*(-50) -243 + j*(-311) -48 + j*(25) --69 + j*(-78) --98 + j*(25) --3 + j*(-18) -63 + j*(-254) --182 + j*(-132) -122 + j*(-55) --43 + j*(161) --257 + j*(219) -1 + j*(-32) -417 + j*(64) --131 + j*(199) --215 + j*(-242) -308 + j*(153) -157 + j*(-10) --199 + j*(164) --77 + j*(-54) --68 + j*(76) --22 + j*(-71) -101 + j*(95) --223 + j*(-192) --94 + j*(113) --256 + j*(-165) -420 + j*(131) -62 + j*(0) --168 + j*(95) --69 + j*(-202) -137 + j*(1) -226 + j*(439) -153 + j*(-33) --76 + j*(81) --264 + j*(30) -400 + j*(62) -175 + j*(-37) -343 + j*(-157) --302 + j*(59) -246 + j*(114) -148 + j*(-61) -112 + j*(74) --134 + j*(-46) --243 + j*(41) -255 + j*(-355) --85 + j*(-38) --110 + j*(183) -132 + j*(95) --566 + j*(169) -313 + j*(162) --31 + j*(-28) --245 + j*(442) --64 + j*(-252) -334 + j*(-138) -105 + j*(-85) --135 + j*(16) -123 + j*(-224) -62 + j*(-48) --78 + j*(-16) --272 + j*(74) -66 + j*(222) -49 + j*(269) --255 + j*(-76) --192 + j*(-3) -11 + j*(-50) -168 + j*(293) -76 + j*(110) --43 + j*(99) -187 + j*(61) --340 + j*(-91) --110 + j*(-132) --156 + j*(-99) -149 + j*(103) -203 + j*(-56) -37 + j*(261) --232 + j*(78) -44 + j*(13) -139 + j*(-14) --58 + j*(-137) --52 + j*(-281) --231 + j*(35) -211 + j*(-35) -42 + j*(65) --177 + j*(223) -127 + j*(61) -148 + j*(-34) -101 + j*(224) --8 + j*(91) --49 + j*(157) --174 + j*(-173) --47 + j*(-56) --55 + j*(115) --108 + j*(-19) --147 + j*(-96) --132 + j*(-86) --23 + j*(23) -183 + j*(-191) -265 + j*(107) --83 + j*(306) -50 + j*(239) -137 + j*(-273) -330 + j*(52) --153 + j*(45) --191 + j*(306) -171 + j*(-64) --16 + j*(78) --298 + j*(-16) -94 + j*(410) --125 + j*(65) --154 + j*(112) -81 + j*(69) --151 + j*(-175) -294 + j*(-264) --119 + j*(286) --35 + j*(-293) -49 + j*(221) --77 + j*(-30) --170 + j*(407) --198 + j*(14) --5 + j*(6) -315 + j*(-35) -41 + j*(282) -241 + j*(25) -148 + j*(168) -34 + j*(196) --248 + j*(161) -129 + j*(-66) -296 + j*(-42) --45 + j*(119) --87 + j*(141) -86 + j*(90) -66 + j*(-45) --13 + j*(-129) -273 + j*(-148) --6 + j*(-82) -227 + j*(-168) -32 + j*(-130) -59 + j*(-64) -11 + j*(99) --91 + j*(-40) -208 + j*(-91) -218 + j*(69) -48 + j*(-325) -6 + j*(47) -6 + j*(-215) --250 + j*(-271) --98 + j*(36) --180 + j*(-23) --371 + j*(-30) --242 + j*(-11) -191 + j*(6) -70 + j*(-28) --90 + j*(171) -208 + j*(-58) -3 + j*(101) -122 + j*(-214) -13 + j*(99) --80 + j*(217) --315 + j*(182) -124 + j*(-228) -192 + j*(177) -330 + j*(61) --270 + j*(-122) --5 + j*(-162) -182 + j*(31) --197 + j*(-168) -11 + j*(123) -86 + j*(277) --37 + j*(-84) -164 + j*(-81) -148 + j*(24) -355 + j*(-25) -149 + j*(54) --36 + j*(158) -189 + j*(-11) -127 + j*(141) -76 + j*(130) --32 + j*(33) --189 + j*(-19) --35 + j*(-350) --133 + j*(252) --139 + j*(-38) -71 + j*(-33) --42 + j*(-138) --252 + j*(121) -283 + j*(140) --50 + j*(135) --124 + j*(-32) -124 + j*(289) --84 + j*(153) -197 + j*(134) --80 + j*(434) --41 + j*(71) -159 + j*(-46) -30 + j*(321) -165 + j*(-438) --47 + j*(98) -180 + j*(125) --144 + j*(-28) -292 + j*(-85) --129 + j*(168) --117 + j*(54) -100 + j*(-224) -25 + j*(-146) -397 + j*(-4) -81 + j*(37) --47 + j*(8) -20 + j*(-333) -110 + j*(-108) --198 + j*(236) --209 + j*(-77) -35 + j*(-111) --82 + j*(78) --46 + j*(-170) -150 + j*(153) -210 + j*(37) --378 + j*(-346) -122 + j*(105) --48 + j*(128) -4 + j*(250) --42 + j*(233) --59 + j*(46) -132 + j*(-116) --69 + j*(51) --296 + j*(228) --81 + j*(40) -121 + j*(-190) -111 + j*(60) --33 + j*(-152) --71 + j*(145) --310 + j*(-11) --144 + j*(-107) -91 + j*(134) --54 + j*(134) -15 + j*(154) -110 + j*(191) --214 + j*(-2) -504 + j*(-209) --42 + j*(-76) -284 + j*(75) --138 + j*(-303) --53 + j*(110) -120 + j*(74) -240 + j*(131) -272 + j*(-115) -3 + j*(69) --32 + j*(18) -259 + j*(-187) -127 + j*(179) --197 + j*(187) -337 + j*(-229) --2 + j*(-35) -188 + j*(25) --348 + j*(177) -138 + j*(-299) --150 + j*(169) -140 + j*(231) --232 + j*(92) --8 + j*(131) --88 + j*(144) -54 + j*(-169) --54 + j*(95) -46 + j*(-153) -74 + j*(112) --187 + j*(-75) --163 + j*(-105) --109 + j*(95) --149 + j*(-81) --320 + j*(128) -245 + j*(117) --284 + j*(93) --26 + j*(-222) --240 + j*(144) -30 + j*(-30) --11 + j*(327) -148 + j*(68) -149 + j*(37) --110 + j*(-209) -348 + j*(7) --69 + j*(-78) -207 + j*(13) --160 + j*(-16) --59 + j*(-75) -70 + j*(7) -203 + j*(220) -301 + j*(210) --206 + j*(-198) -24 + j*(115) --163 + j*(-298) -115 + j*(104) -222 + j*(290) --147 + j*(-90) --254 + j*(-416) -123 + j*(-111) -11 + j*(-310) --179 + j*(-358) -334 + j*(-325) --4 + j*(-132) -35 + j*(134) -5 + j*(-226) -243 + j*(-151) -28 + j*(15) --40 + j*(62) -37 + j*(179) -308 + j*(-266) --185 + j*(-283) -116 + j*(107) -374 + j*(-155) -270 + j*(137) --241 + j*(292) -170 + j*(-226) -55 + j*(-2) -40 + j*(-28) --175 + j*(8) --221 + j*(-73) --51 + j*(-106) --148 + j*(-103) -109 + j*(143) -6 + j*(203) -149 + j*(239) --368 + j*(-54) -95 + j*(249) -210 + j*(64) -13 + j*(-30) -302 + j*(80) -409 + j*(-78) -76 + j*(-308) --71 + j*(-169) --23 + j*(-222) -33 + j*(80) --338 + j*(-320) -45 + j*(-105) --66 + j*(-274) -70 + j*(-21) -48 + j*(27) -189 + j*(257) --64 + j*(7) --117 + j*(-42) --28 + j*(-128) --148 + j*(-406) --174 + j*(-208) -198 + j*(-69) -147 + j*(-133) -257 + j*(-138) --231 + j*(17) -127 + j*(-88) -88 + j*(42) --126 + j*(36) --63 + j*(-175) -123 + j*(-173) --252 + j*(-136) --198 + j*(122) --290 + j*(237) -22 + j*(-23) -171 + j*(89) -239 + j*(-141) -11 + j*(-109) -301 + j*(-88) --216 + j*(1) -14 + j*(-177) -47 + j*(6) --161 + j*(20) --186 + j*(-78) -173 + j*(-47) --289 + j*(-68) --81 + j*(83) --77 + j*(164) -220 + j*(-20) --106 + j*(177) --292 + j*(-216) -74 + j*(-34) -245 + j*(1) -4 + j*(383) --30 + j*(-119) -221 + j*(180) -139 + j*(-260) --160 + j*(95) -58 + j*(361) --223 + j*(57) --59 + j*(-59) --82 + j*(-51) -105 + j*(35) -59 + j*(146) --158 + j*(-41) --64 + j*(197) --202 + j*(-83) -191 + j*(-335) -129 + j*(-421) --30 + j*(-118) -69 + j*(129) --116 + j*(-67) --366 + j*(-18) -279 + j*(235) --279 + j*(1) -45 + j*(-96) --13 + j*(-238) -382 + j*(-21) -207 + j*(351) -192 + j*(-107) --103 + j*(-137) --90 + j*(110) --262 + j*(-211) --127 + j*(162) -109 + j*(40) --238 + j*(127) -81 + j*(5) --30 + j*(109) -118 + j*(71) --12 + j*(26) -40 + j*(-161) -23 + j*(124) --23 + j*(25) --374 + j*(-62) -154 + j*(448) --66 + j*(-63) -152 + j*(-354) -409 + j*(-129) --469 + j*(96) --4 + j*(-141) --13 + j*(142) -276 + j*(12) --135 + j*(-289) --50 + j*(181) --205 + j*(-146) -196 + j*(255) --200 + j*(23) -279 + j*(52) --76 + j*(196) -40 + j*(98) --62 + j*(211) -74 + j*(73) --161 + j*(-179) --134 + j*(-2) --18 + j*(-132) -444 + j*(21) --194 + j*(69) --92 + j*(25) --119 + j*(-431) -121 + j*(136) --100 + j*(63) -14 + j*(-67) -66 + j*(234) --35 + j*(288) -356 + j*(-111) --74 + j*(-60) -215 + j*(206) --46 + j*(8) --4 + j*(-153) --135 + j*(-165) -274 + j*(-99) --218 + j*(-60) --7 + j*(145) --282 + j*(-132) --21 + j*(-270) -35 + j*(-186) -59 + j*(161) --148 + j*(-212) --452 + j*(-222) -203 + j*(-168) -16 + j*(142) -177 + j*(448) -56 + j*(-74) --37 + j*(119) --47 + j*(48) -192 + j*(30) --243 + j*(67) --199 + j*(78) -197 + j*(103) -164 + j*(-210) --33 + j*(185) --55 + j*(35) --388 + j*(21) --49 + j*(-101) --27 + j*(-276) --197 + j*(-151) --236 + j*(-178) --32 + j*(-162) --78 + j*(257) --75 + j*(85) -157 + j*(-10) --147 + j*(-3) -21 + j*(-8) -120 + j*(120) -132 + j*(98) --140 + j*(-98) -194 + j*(-322) -113 + j*(-51) -177 + j*(-63) -41 + j*(204) -146 + j*(45) --145 + j*(62) -17 + j*(74) -257 + j*(-247) --16 + j*(-193) --33 + j*(-364) --297 + j*(100) -18 + j*(-268) --79 + j*(-70) -49 + j*(17) --61 + j*(-52) -296 + j*(-32) -37 + j*(168) --117 + j*(-164) --74 + j*(-211) --87 + j*(66) --165 + j*(-38) -18 + j*(136) -14 + j*(74) -187 + j*(172) -99 + j*(22) -95 + j*(-151) -88 + j*(-236) --201 + j*(92) -91 + j*(214) -280 + j*(200) -254 + j*(-28) -82 + j*(199) --333 + j*(294) --64 + j*(-255) -228 + j*(375) --1 + j*(94) -211 + j*(-207) -299 + j*(-447) --104 + j*(-17) --30 + j*(-28) --164 + j*(-211) --87 + j*(-76) --124 + j*(264) -176 + j*(-222) -221 + j*(-322) -158 + j*(148) --307 + j*(-128) -86 + j*(9) --10 + j*(-23) -131 + j*(25) --108 + j*(186) --144 + j*(132) -67 + j*(121) -11 + j*(-222) -1 + j*(93) -182 + j*(93) --114 + j*(200) -87 + j*(163) -88 + j*(86) --73 + j*(-90) -123 + j*(-30) --16 + j*(-27) -214 + j*(-188) --36 + j*(25) --286 + j*(310) --202 + j*(-54) --223 + j*(238) --161 + j*(54) --62 + j*(170) --214 + j*(-35) -110 + j*(264) -262 + j*(265) -100 + j*(37) --488 + j*(305) --148 + j*(254) --253 + j*(123) -146 + j*(182) --332 + j*(-199) -55 + j*(-65) -204 + j*(83) --1 + j*(-51) -32 + j*(-314) -43 + j*(23) -68 + j*(-412) -78 + j*(-180) --197 + j*(146) --76 + j*(-66) -136 + j*(-226) -40 + j*(241) -27 + j*(-177) --144 + j*(66) -112 + j*(-258) -163 + j*(-74) --1 + j*(-81) -52 + j*(469) -3 + j*(-276) -148 + j*(107) --93 + j*(-173) -64 + j*(37) --231 + j*(124) -61 + j*(-131) --88 + j*(114) -107 + j*(-32) --170 + j*(240) -226 + j*(-173) -58 + j*(-247) -22 + j*(47) -168 + j*(181) -16 + j*(158) --120 + j*(-66) --81 + j*(296) --209 + j*(-192) --75 + j*(-115) -95 + j*(86) -32 + j*(125) -57 + j*(64) -6 + j*(-11) --367 + j*(-47) -180 + j*(-28) --443 + j*(-35) --174 + j*(67) --83 + j*(-21) -64 + j*(-84) -206 + j*(-67) -25 + j*(-205) --205 + j*(139) -16 + j*(-135) --233 + j*(-43) -158 + j*(-4) --18 + j*(-106) --87 + j*(129) --112 + j*(-28) -159 + j*(144) -98 + j*(-110) --11 + j*(28) --41 + j*(192) -21 + j*(-199) --26 + j*(233) -6 + j*(-337) -412 + j*(7) --136 + j*(-25) -83 + j*(103) --45 + j*(62) -79 + j*(20) -86 + j*(20) -142 + j*(284) --45 + j*(-91) -100 + j*(67) --142 + j*(100) --223 + j*(248) --3 + j*(120) -311 + j*(-245) -62 + j*(-47) -91 + j*(-78) --141 + j*(-132) -4 + j*(-133) -81 + j*(-179) --13 + j*(166) -20 + j*(180) -182 + j*(-139) -230 + j*(83) -387 + j*(67) --6 + j*(-113) -63 + j*(161) --198 + j*(104) --36 + j*(-129) --30 + j*(-63) -112 + j*(-41) -127 + j*(189) -156 + j*(62) --110 + j*(-12) -52 + j*(-182) --110 + j*(-298) --151 + j*(180) -234 + j*(-178) -14 + j*(69) -75 + j*(-57) -236 + j*(-168) --54 + j*(-212) --194 + j*(15) -80 + j*(347) -190 + j*(412) -11 + j*(-153) -59 + j*(28) --182 + j*(-11) -54 + j*(145) -69 + j*(78) -166 + j*(-189) -204 + j*(-157) -83 + j*(-216) -87 + j*(-35) --200 + j*(-156) -455 + j*(141) -7 + j*(-114) -91 + j*(305) --95 + j*(62) --254 + j*(-61) --80 + j*(117) --30 + j*(-195) --146 + j*(105) -21 + j*(-25) -305 + j*(23) --81 + j*(-15) -192 + j*(395) -141 + j*(303) --52 + j*(-129) -54 + j*(-149) -63 + j*(64) -98 + j*(-260) -132 + j*(19) --59 + j*(-57) -116 + j*(170) -251 + j*(-284) -42 + j*(208) -51 + j*(-195) --98 + j*(-44) --57 + j*(55) -106 + j*(-38) --243 + j*(16) -153 + j*(-65) -7 + j*(-110) -88 + j*(-73) --279 + j*(77) --173 + j*(40) --112 + j*(0) --154 + j*(-228) -2 + j*(-147) --166 + j*(126) -119 + j*(148) --215 + j*(114) --155 + j*(23) --41 + j*(-34) -40 + j*(-300) --328 + j*(202) --206 + j*(-212) -59 + j*(-325) -25 + j*(-100) --208 + j*(-235) --233 + j*(167) --243 + j*(20) --203 + j*(0) --168 + j*(-173) --310 + j*(-146) --148 + j*(398) --72 + j*(-93) -62 + j*(-152) -28 + j*(128) --217 + j*(-27) --222 + j*(-188) -168 + j*(16) --100 + j*(140) -99 + j*(8) -76 + j*(-57) -139 + j*(-150) --192 + j*(-49) --18 + j*(-206) --16 + j*(-327) -78 + j*(35) -11 + j*(42) --107 + j*(-82) --274 + j*(235) -81 + j*(-11) -281 + j*(-61) --148 + j*(78) --279 + j*(-51) --252 + j*(186) -31 + j*(-99) -292 + j*(-155) --188 + j*(192) -258 + j*(-96) -21 + j*(-92) --28 + j*(165) -146 + j*(59) -0 + j*(-21) -30 + j*(-192) -82 + j*(14) --294 + j*(-13) --150 + j*(137) --71 + j*(68) --233 + j*(45) -12 + j*(-62) --177 + j*(44) --175 + j*(337) --41 + j*(1) -363 + j*(-244) -231 + j*(181) -191 + j*(-130) -287 + j*(115) --69 + j*(221) --236 + j*(-50) --393 + j*(-47) -71 + j*(13) -447 + j*(-110) --76 + j*(316) -42 + j*(71) --20 + j*(-75) --17 + j*(82) --231 + j*(-258) -156 + j*(-174) --85 + j*(-142) --165 + j*(-173) --185 + j*(-25) -173 + j*(137) -303 + j*(-119) --86 + j*(-105) --253 + j*(-318) --68 + j*(142) --213 + j*(259) -179 + j*(-58) --93 + j*(122) -135 + j*(-185) --1 + j*(-180) -261 + j*(-385) --207 + j*(-315) -6 + j*(-70) -216 + j*(339) --137 + j*(-129) -35 + j*(15) -16 + j*(127) -71 + j*(-29) --254 + j*(-211) --325 + j*(103) --222 + j*(6) -159 + j*(91) -25 + j*(106) --139 + j*(101) --133 + j*(-289) --124 + j*(-40) --238 + j*(-183) --144 + j*(-1) -111 + j*(-64) -63 + j*(-308) --78 + j*(-153) -324 + j*(-243) -209 + j*(11) -64 + j*(232) -71 + j*(62) -203 + j*(-52) --161 + j*(129) --339 + j*(144) -78 + j*(86) -66 + j*(-263) --78 + j*(-190) -247 + j*(293) --25 + j*(19) --267 + j*(-15) -89 + j*(-206) --64 + j*(120) -83 + j*(165) --195 + j*(249) --55 + j*(-379) --194 + j*(19) --139 + j*(49) -316 + j*(-139) --190 + j*(170) --33 + j*(34) -14 + j*(-44) --363 + j*(50) -39 + j*(77) -296 + j*(-133) --183 + j*(289) --96 + j*(-81) --74 + j*(-333) -92 + j*(-183) --99 + j*(167) --63 + j*(21) -339 + j*(-39) --175 + j*(-257) -72 + j*(117) --192 + j*(105) -17 + j*(-17) --84 + j*(166) -49 + j*(188) --156 + j*(153) -74 + j*(-169) --35 + j*(280) --81 + j*(101) -9 + j*(112) -214 + j*(-38) -254 + j*(-35) -78 + j*(263) -125 + j*(-71) -100 + j*(68) -339 + j*(111) --10 + j*(134) --4 + j*(-69) --98 + j*(74) --41 + j*(106) --28 + j*(330) -325 + j*(88) --59 + j*(41) --110 + j*(-247) -154 + j*(16) -463 + j*(363) --112 + j*(-29) -133 + j*(-1) -315 + j*(208) --102 + j*(-248) -135 + j*(23) -328 + j*(11) -201 + j*(46) -163 + j*(134) -224 + j*(-62) -178 + j*(-89) -136 + j*(107) -69 + j*(-224) -140 + j*(-87) --112 + j*(254) --65 + j*(120) --239 + j*(-35) -80 + j*(30) --331 + j*(-125) --71 + j*(45) -31 + j*(417) --17 + j*(-139) --54 + j*(49) -246 + j*(-253) --6 + j*(101) -110 + j*(-138) --88 + j*(56) -66 + j*(264) --255 + j*(-18) --155 + j*(95) --332 + j*(88) --103 + j*(25) --618 + j*(214) -213 + j*(-211) -260 + j*(-49) --94 + j*(-75) --9 + j*(12) -97 + j*(171) -74 + j*(219) --18 + j*(-54) -101 + j*(-135) --159 + j*(82) --48 + j*(-196) -408 + j*(275) --194 + j*(-74) -111 + j*(337) --13 + j*(409) --106 + j*(-51) --178 + j*(-203) --228 + j*(-69) --243 + j*(-10) -1 + j*(-8) -177 + j*(-189) -85 + j*(16) -131 + j*(270) --96 + j*(226) --4 + j*(336) --217 + j*(42) --99 + j*(-82) --206 + j*(-93) -18 + j*(295) -99 + j*(-189) --350 + j*(129) --8 + j*(91) -59 + j*(-274) --83 + j*(173) -48 + j*(29) -207 + j*(-75) -49 + j*(78) --65 + j*(-382) -193 + j*(100) --70 + j*(42) -33 + j*(-206) -228 + j*(49) -53 + j*(208) --76 + j*(-93) -102 + j*(-103) --256 + j*(-43) -86 + j*(-13) --111 + j*(40) -186 + j*(-48) --2 + j*(498) --182 + j*(52) --127 + j*(81) -74 + j*(-54) -38 + j*(-88) -35 + j*(-194) --173 + j*(112) --129 + j*(224) --54 + j*(-2) -191 + j*(113) --88 + j*(72) --69 + j*(-259) -84 + j*(240) --187 + j*(70) --79 + j*(-11) -259 + j*(206) -123 + j*(365) -92 + j*(103) --187 + j*(76) -54 + j*(232) -40 + j*(-158) --212 + j*(-424) --91 + j*(215) --112 + j*(138) --110 + j*(243) --110 + j*(145) -72 + j*(80) -30 + j*(-110) -180 + j*(26) -63 + j*(5) -232 + j*(238) -199 + j*(-119) -438 + j*(64) --40 + j*(-139) --146 + j*(-31) -85 + j*(167) -139 + j*(-206) -45 + j*(66) -98 + j*(-75) -23 + j*(131) -131 + j*(15) --84 + j*(126) --64 + j*(-182) -28 + j*(141) -17 + j*(37) -194 + j*(6) --4 + j*(336) -160 + j*(205) --259 + j*(113) --52 + j*(4) --104 + j*(-249) --11 + j*(-245) --66 + j*(86) -30 + j*(-138) -90 + j*(-182) -47 + j*(122) -281 + j*(166) --230 + j*(13) --165 + j*(380) -222 + j*(-15) --247 + j*(113) --91 + j*(-12) --88 + j*(200) --69 + j*(240) --165 + j*(-6) --124 + j*(-184) --327 + j*(296) --209 + j*(37) --114 + j*(-329) -238 + j*(-267) --122 + j*(-149) --104 + j*(-238) -339 + j*(264) -347 + j*(76) -184 + j*(-87) -272 + j*(-118) -10 + j*(169) -23 + j*(74) --53 + j*(377) --180 + j*(-162) --35 + j*(-269) -73 + j*(280) --176 + j*(-9) -69 + j*(172) --14 + j*(101) --124 + j*(-119) --54 + j*(-187) --47 + j*(158) -352 + j*(147) -167 + j*(312) --187 + j*(-197) -101 + j*(202) --170 + j*(-168) -140 + j*(39) -132 + j*(40) -29 + j*(-33) --226 + j*(204) --341 + j*(-25) --21 + j*(235) -110 + j*(25) --176 + j*(40) --35 + j*(105) --175 + j*(13) --85 + j*(-78) --216 + j*(-102) -147 + j*(43) -370 + j*(-45) --330 + j*(-246) --337 + j*(179) --133 + j*(67) -110 + j*(-80) -92 + j*(-27) -199 + j*(-197) -150 + j*(98) --129 + j*(79) --209 + j*(-61) --128 + j*(406) -472 + j*(301) --19 + j*(146) --18 + j*(-83) --54 + j*(-16) -121 + j*(76) --417 + j*(77) --192 + j*(-91) -35 + j*(232) -240 + j*(161) --132 + j*(-16) --149 + j*(72) --26 + j*(-36) --112 + j*(-83) --86 + j*(-100) -83 + j*(-132) --123 + j*(53) --269 + j*(-47) --93 + j*(180) -129 + j*(200) --218 + j*(105) -116 + j*(98) --157 + j*(-165) --252 + j*(-54) -87 + j*(91) -309 + j*(-156) -72 + j*(-159) --16 + j*(-136) --54 + j*(16) --103 + j*(170) -76 + j*(182) --231 + j*(-148) -47 + j*(169) -21 + j*(163) -84 + j*(261) -198 + j*(223) --277 + j*(100) --166 + j*(-125) -125 + j*(-30) --276 + j*(266) -159 + j*(26) -311 + j*(171) --404 + j*(289) --104 + j*(-370) -172 + j*(-347) -59 + j*(-465) --428 + j*(43) -26 + j*(-619) --139 + j*(192) -213 + j*(469) -395 + j*(104) -146 + j*(-270) -77 + j*(257) --204 + j*(245) -61 + j*(264) -317 + j*(351) -395 + j*(379) --250 + j*(-278) -547 + j*(-360) --296 + j*(-69) -71 + j*(260) -456 + j*(-113) -316 + j*(214) -107 + j*(-390) -313 + j*(228) --105 + j*(486) -120 + j*(275) -541 + j*(-306) --351 + j*(-19) --144 + j*(-456) -103 + j*(-197) --262 + j*(-299) -305 + j*(62) --245 + j*(-17) --219 + j*(472) -200 + j*(-195) --155 + j*(-257) --211 + j*(341) -146 + j*(262) --86 + j*(229) --245 + j*(-318) -368 + j*(-296) --375 + j*(305) --582 + j*(149) -412 + j*(-397) -421 + j*(-441) -434 + j*(-191) -141 + j*(325) --331 + j*(88) -610 + j*(43) --328 + j*(305) -351 + j*(-415) -161 + j*(428) -530 + j*(142) --705 + j*(-324) --76 + j*(132) --316 + j*(-183) --307 + j*(187) -148 + j*(361) -183 + j*(94) --168 + j*(360) --266 + j*(129) --301 + j*(-244) --252 + j*(232) --546 + j*(216) --227 + j*(121) --35 + j*(-342) --190 + j*(-325) --59 + j*(523) --171 + j*(-315) -297 + j*(183) -194 + j*(148) --443 + j*(281) --512 + j*(-66) -532 + j*(250) --276 + j*(306) --358 + j*(187) --477 + j*(518) --310 + j*(-158) -167 + j*(-405) -66 + j*(-134) -96 + j*(379) --23 + j*(-460) --404 + j*(-227) --14 + j*(-501) --691 + j*(-200) --339 + j*(30) -648 + j*(317) -347 + j*(-322) --260 + j*(597) --610 + j*(216) -443 + j*(205) -249 + j*(-314) -486 + j*(-170) --298 + j*(87) -141 + j*(238) --60 + j*(-71) -67 + j*(-124) --291 + j*(-540) -174 + j*(-324) --161 + j*(-228) -193 + j*(-37) --153 + j*(-331) -235 + j*(293) --141 + j*(-504) -339 + j*(49) -373 + j*(21) -473 + j*(355) --270 + j*(268) --26 + j*(-260) -379 + j*(-419) -178 + j*(-35) -307 + j*(680) -564 + j*(-397) --474 + j*(-527) -482 + j*(207) -374 + j*(51) -3 + j*(123) -5 + j*(586) -267 + j*(491) -185 + j*(225) -312 + j*(556) -4 + j*(-366) -166 + j*(405) --346 + j*(422) --438 + j*(-416) -390 + j*(-59) -30 + j*(-288) -274 + j*(-242) --114 + j*(-100) --177 + j*(-375) --455 + j*(-292) --272 + j*(301) --218 + j*(-479) -447 + j*(-296) --335 + j*(-378) --427 + j*(-16) -308 + j*(-300) -479 + j*(322) --170 + j*(82) --366 + j*(-153) --701 + j*(-477) --350 + j*(282) --327 + j*(344) --389 + j*(-333) --450 + j*(-218) --3 + j*(682) -260 + j*(-402) -70 + j*(305) -588 + j*(520) --1 + j*(-161) --292 + j*(-104) --267 + j*(434) --195 + j*(404) --435 + j*(542) --376 + j*(-235) --187 + j*(42) -61 + j*(550) --125 + j*(93) --262 + j*(217) -512 + j*(234) -405 + j*(358) -52 + j*(-291) -1 + j*(395) -450 + j*(-216) --172 + j*(432) --180 + j*(-247) -15 + j*(-400) --78 + j*(363) -227 + j*(123) -403 + j*(-133) --124 + j*(258) --400 + j*(-366) -72 + j*(-175) --140 + j*(-51) -90 + j*(-166) --484 + j*(148) --404 + j*(-392) --197 + j*(133) -241 + j*(-45) -122 + j*(-306) --136 + j*(296) --194 + j*(264) -516 + j*(-226) --168 + j*(-320) --14 + j*(-386) -231 + j*(440) -146 + j*(346) -268 + j*(451) -184 + j*(-27) -310 + j*(214) -409 + j*(-258) --361 + j*(-303) -153 + j*(-127) --217 + j*(-438) -107 + j*(476) --204 + j*(403) --313 + j*(315) --328 + j*(-307) --351 + j*(97) -185 + j*(-211) -122 + j*(233) --445 + j*(-503) --212 + j*(-397) --420 + j*(196) -64 + j*(-252) -407 + j*(-336) --265 + j*(280) -281 + j*(-268) -218 + j*(-292) --138 + j*(484) --16 + j*(192) -474 + j*(362) --399 + j*(-2) -73 + j*(-350) -264 + j*(158) -365 + j*(-137) -71 + j*(-62) --389 + j*(-485) --74 + j*(-57) --281 + j*(252) -299 + j*(258) -1 + j*(200) -252 + j*(44) -95 + j*(-210) -180 + j*(-445) --356 + j*(228) -90 + j*(-321) --198 + j*(-281) -441 + j*(-279) --417 + j*(428) --317 + j*(-210) -156 + j*(-520) --59 + j*(-228) -238 + j*(-274) --299 + j*(-308) --270 + j*(-294) --181 + j*(-165) -180 + j*(-48) --172 + j*(-289) -395 + j*(77) -212 + j*(-88) -361 + j*(378) --260 + j*(-753) -205 + j*(-86) --151 + j*(127) -416 + j*(-146) -121 + j*(-566) -65 + j*(-477) -119 + j*(281) -43 + j*(-42) --172 + j*(182) --340 + j*(396) -51 + j*(286) -235 + j*(-410) -296 + j*(-146) --86 + j*(-184) --59 + j*(-322) --381 + j*(236) -98 + j*(-173) --176 + j*(218) --682 + j*(-62) --41 + j*(-211) --525 + j*(-330) -36 + j*(-36) --578 + j*(-367) --245 + j*(380) --305 + j*(301) -333 + j*(-141) --127 + j*(-254) -308 + j*(-378) --358 + j*(177) -231 + j*(216) --112 + j*(459) --436 + j*(-497) -296 + j*(231) --276 + j*(-409) -299 + j*(144) -310 + j*(-267) --309 + j*(-237) --204 + j*(104) -158 + j*(194) -325 + j*(-127) -140 + j*(260) -52 + j*(131) -29 + j*(-135) --162 + j*(345) --5 + j*(132) -69 + j*(-456) -302 + j*(149) -211 + j*(-262) --506 + j*(-175) -292 + j*(182) -52 + j*(-322) -365 + j*(-232) -312 + j*(-269) --319 + j*(21) --315 + j*(-581) --138 + j*(167) --43 + j*(197) --42 + j*(450) --296 + j*(155) --540 + j*(358) --307 + j*(87) --446 + j*(-250) -97 + j*(116) -140 + j*(-486) -300 + j*(-278) --419 + j*(163) --211 + j*(-185) --194 + j*(367) -291 + j*(250) -312 + j*(-236) -195 + j*(81) --465 + j*(-375) -482 + j*(115) -116 + j*(120) -122 + j*(320) --55 + j*(-224) --280 + j*(177) -542 + j*(-264) -416 + j*(103) --152 + j*(-113) --116 + j*(-58) --139 + j*(-262) --165 + j*(-510) --57 + j*(-504) -168 + j*(-228) -474 + j*(-120) --119 + j*(10) -313 + j*(-328) --291 + j*(209) -271 + j*(-57) -358 + j*(-245) -419 + j*(-226) --45 + j*(-529) -344 + j*(-443) -147 + j*(-416) --105 + j*(-279) -40 + j*(4) --409 + j*(212) --322 + j*(-257) --169 + j*(-639) --194 + j*(-323) -311 + j*(-214) --356 + j*(559) -318 + j*(-374) -157 + j*(112) --339 + j*(76) --456 + j*(153) --328 + j*(-325) -504 + j*(113) --447 + j*(219) -173 + j*(284) -194 + j*(-21) --136 + j*(-310) --91 + j*(351) --112 + j*(-317) -474 + j*(227) --348 + j*(124) -368 + j*(-102) -395 + j*(-190) --172 + j*(202) --148 + j*(-287) -393 + j*(-330) -144 + j*(411) --259 + j*(238) -371 + j*(-130) -40 + j*(-457) -129 + j*(-453) --451 + j*(-215) --333 + j*(242) -353 + j*(334) --604 + j*(356) -209 + j*(-318) --358 + j*(-76) --118 + j*(-313) -439 + j*(-315) -60 + j*(-572) --457 + j*(282) --834 + j*(-7) -428 + j*(-140) -325 + j*(215) -42 + j*(263) -301 + j*(151) -140 + j*(-72) -489 + j*(-438) -323 + j*(-402) -194 + j*(-13) -257 + j*(-322) --334 + j*(267) -231 + j*(409) --231 + j*(-271) --265 + j*(394) --324 + j*(-305) --588 + j*(-325) -84 + j*(-489) -366 + j*(43) --291 + j*(108) -533 + j*(-455) --100 + j*(352) -181 + j*(-187) -287 + j*(-428) --322 + j*(17) -90 + j*(-332) -413 + j*(-171) --474 + j*(-153) --167 + j*(-209) -76 + j*(-141) -395 + j*(201) --330 + j*(212) -127 + j*(-255) -120 + j*(-15) --132 + j*(190) --436 + j*(-209) --281 + j*(425) -300 + j*(-408) --162 + j*(-301) --316 + j*(-458) -166 + j*(-491) --384 + j*(-423) -568 + j*(-527) --212 + j*(296) --204 + j*(-298) --229 + j*(117) --159 + j*(-412) -365 + j*(358) -260 + j*(-245) -247 + j*(33) -162 + j*(139) --332 + j*(284) --489 + j*(-540) --221 + j*(-39) --55 + j*(-142) --129 + j*(360) -235 + j*(-252) -513 + j*(104) --58 + j*(-313) -419 + j*(284) --267 + j*(316) -588 + j*(-197) --193 + j*(-361) -370 + j*(556) --269 + j*(106) -153 + j*(-44) --167 + j*(-265) --21 + j*(240) -324 + j*(-368) --233 + j*(-361) --260 + j*(-260) --504 + j*(245) --684 + j*(316) --13 + j*(-153) -89 + j*(-546) -268 + j*(-261) -392 + j*(448) -359 + j*(397) -448 + j*(-398) --400 + j*(-225) --547 + j*(-383) -399 + j*(429) --360 + j*(-187) -36 + j*(-126) --384 + j*(291) -158 + j*(-358) -337 + j*(569) -431 + j*(-49) -581 + j*(30) -158 + j*(-206) -361 + j*(-217) --216 + j*(-233) -309 + j*(-486) -258 + j*(-265) -363 + j*(199) --440 + j*(309) --134 + j*(-397) -441 + j*(298) -356 + j*(285) -148 + j*(-550) -207 + j*(86) -537 + j*(395) --137 + j*(297) --80 + j*(409) -696 + j*(23) -25 + j*(-275) -402 + j*(129) -334 + j*(219) -79 + j*(271) --461 + j*(-98) -21 + j*(-23) --138 + j*(354) -487 + j*(-36) -373 + j*(-1) --540 + j*(-255) -108 + j*(-153) -232 + j*(249) -262 + j*(136) --284 + j*(-388) -254 + j*(-303) -4 + j*(-573) --71 + j*(327) --25 + j*(-76) --33 + j*(-450) -248 + j*(362) -61 + j*(-260) -288 + j*(272) -245 + j*(-42) --204 + j*(277) --479 + j*(-407) --165 + j*(451) -409 + j*(445) --143 + j*(566) --254 + j*(-428) --61 + j*(408) --203 + j*(-141) --38 + j*(893) --53 + j*(235) -170 + j*(-614) -217 + j*(180) -499 + j*(-375) --339 + j*(232) --112 + j*(-235) -290 + j*(233) --400 + j*(214) -470 + j*(363) --634 + j*(-109) --344 + j*(45) -308 + j*(-479) --330 + j*(-6) --141 + j*(-100) --275 + j*(195) -474 + j*(139) -23 + j*(482) --501 + j*(-599) --23 + j*(105) -204 + j*(-323) -220 + j*(119) -471 + j*(-33) --176 + j*(-472) --64 + j*(-11) --98 + j*(158) -94 + j*(-177) --395 + j*(-368) -106 + j*(106) --556 + j*(-269) -404 + j*(389) --13 + j*(-54) --25 + j*(455) -2 + j*(366) -418 + j*(-81) -390 + j*(-341) --173 + j*(-397) -364 + j*(-233) -17 + j*(-495) --489 + j*(86) --287 + j*(419) -93 + j*(431) --31 + j*(212) --218 + j*(-117) --233 + j*(244) -1 + j*(130) --180 + j*(-312) --434 + j*(57) -501 + j*(22) -324 + j*(-359) --497 + j*(-63) -453 + j*(-11) -225 + j*(-460) --413 + j*(-100) --16 + j*(440) -500 + j*(130) --414 + j*(161) -469 + j*(326) -211 + j*(175) -332 + j*(-65) -407 + j*(13) -207 + j*(467) --366 + j*(372) -200 + j*(-223) --301 + j*(-318) --198 + j*(-273) --209 + j*(221) --148 + j*(5) -102 + j*(433) --107 + j*(-116) -303 + j*(337) -356 + j*(98) --203 + j*(369) -452 + j*(281) --542 + j*(421) -54 + j*(371) -222 + j*(-46) -559 + j*(544) -100 + j*(-298) -68 + j*(204) --264 + j*(-267) --97 + j*(-311) --738 + j*(203) -282 + j*(342) --310 + j*(778) --209 + j*(102) -154 + j*(-2) -11 + j*(-8) -153 + j*(222) -4 + j*(-33) -309 + j*(283) --8 + j*(117) --136 + j*(-322) -35 + j*(33) --11 + j*(176) -119 + j*(237) -186 + j*(45) -77 + j*(124) -288 + j*(35) --57 + j*(216) -101 + j*(-8) -119 + j*(-40) -102 + j*(-182) -15 + j*(83) --88 + j*(74) -187 + j*(388) --7 + j*(-26) -284 + j*(-194) -235 + j*(-341) --86 + j*(-122) --98 + j*(-227) --177 + j*(-59) --202 + j*(-35) --58 + j*(-23) --12 + j*(-45) -83 + j*(33) --135 + j*(-110) --112 + j*(-204) --404 + j*(-49) --187 + j*(-67) --158 + j*(168) --105 + j*(-175) -13 + j*(-358) -4 + j*(-224) -35 + j*(-62) -120 + j*(-361) --274 + j*(-179) --63 + j*(23) --110 + j*(-18) --194 + j*(-4) --61 + j*(-28) -138 + j*(-290) -100 + j*(-38) --128 + j*(-204) --246 + j*(-176) -397 + j*(33) -180 + j*(80) --214 + j*(-113) --52 + j*(244) --95 + j*(-3) --87 + j*(-13) -15 + j*(73) -71 + j*(-78) -110 + j*(-1) -4 + j*(-154) -65 + j*(-86) --14 + j*(100) --88 + j*(21) --117 + j*(120) --478 + j*(-64) --50 + j*(-23) -217 + j*(10) --46 + j*(-238) -60 + j*(-23) -235 + j*(-35) --79 + j*(339) --192 + j*(-21) --89 + j*(135) --107 + j*(126) --221 + j*(42) -211 + j*(184) -66 + j*(-160) --168 + j*(-4) --105 + j*(85) -132 + j*(-27) -124 + j*(-130) -174 + j*(-112) -151 + j*(76) -249 + j*(-163) -72 + j*(233) --243 + j*(-77) --294 + j*(-25) --281 + j*(61) -112 + j*(67) --37 + j*(13) -74 + j*(-144) --168 + j*(-35) --13 + j*(-313) --386 + j*(10) --311 + j*(-79) --11 + j*(90) -185 + j*(405) -186 + j*(-17) --127 + j*(-137) -10 + j*(136) --59 + j*(110) -1 + j*(-83) --20 + j*(-180) -214 + j*(361) -231 + j*(62) --104 + j*(-86) --192 + j*(185) --108 + j*(170) --169 + j*(-192) --104 + j*(-171) --28 + j*(-57) --208 + j*(126) -185 + j*(-78) -105 + j*(159) --228 + j*(-110) -340 + j*(82) -235 + j*(214) --80 + j*(-14) -234 + j*(-162) --131 + j*(63) --43 + j*(60) --157 + j*(68) --207 + j*(144) --77 + j*(53) -214 + j*(147) --150 + j*(-83) --100 + j*(90) --43 + j*(90) -97 + j*(129) --34 + j*(-44) -14 + j*(86) --258 + j*(47) -161 + j*(38) -286 + j*(-1) -113 + j*(178) --124 + j*(-255) --3 + j*(347) -136 + j*(-137) -62 + j*(-89) -36 + j*(267) --74 + j*(-311) --1 + j*(109) -96 + j*(-269) -223 + j*(-111) -298 + j*(-105) --149 + j*(9) --303 + j*(36) --265 + j*(276) --324 + j*(-81) --176 + j*(-8) -243 + j*(311) --18 + j*(-35) --212 + j*(177) --35 + j*(158) -20 + j*(121) -70 + j*(64) --201 + j*(-1) --76 + j*(258) --252 + j*(101) -2 + j*(225) -92 + j*(-81) -123 + j*(-123) --125 + j*(78) -146 + j*(-37) -184 + j*(375) -62 + j*(102) --294 + j*(196) --3 + j*(217) --214 + j*(322) -559 + j*(98) --136 + j*(173) -47 + j*(-37) -98 + j*(-22) -234 + j*(-21) -36 + j*(-142) -239 + j*(-272) --58 + j*(198) -390 + j*(37) --132 + j*(-216) --95 + j*(-52) -27 + j*(-119) --8 + j*(143) -122 + j*(110) -145 + j*(-146) -210 + j*(-166) --73 + j*(-25) -136 + j*(45) -150 + j*(-169) -45 + j*(-17) -122 + j*(-30) -110 + j*(-110) -63 + j*(-232) -330 + j*(312) --204 + j*(-26) -204 + j*(129) --87 + j*(88) -240 + j*(73) -129 + j*(-101) --68 + j*(92) -115 + j*(122) -273 + j*(103) --320 + j*(-144) -79 + j*(93) --335 + j*(242) -308 + j*(1) -52 + j*(119) -206 + j*(-37) -106 + j*(-74) --288 + j*(-274) --131 + j*(194) --107 + j*(-123) --418 + j*(120) -165 + j*(74) -209 + j*(27) -143 + j*(-276) -12 + j*(-70) -33 + j*(-74) --44 + j*(-145) -1 + j*(-385) -7 + j*(45) -460 + j*(-204) -53 + j*(266) --216 + j*(-86) -28 + j*(92) -118 + j*(61) -168 + j*(-52) -110 + j*(198) -121 + j*(-107) -98 + j*(75) --211 + j*(338) -16 + j*(-6) --261 + j*(346) -101 + j*(-113) --151 + j*(104) --111 + j*(-175) -38 + j*(172) -83 + j*(-206) -173 + j*(199) --34 + j*(66) --12 + j*(-31) -40 + j*(47) -30 + j*(336) -276 + j*(16) -238 + j*(76) -439 + j*(259) -120 + j*(-16) -125 + j*(37) -139 + j*(104) --79 + j*(-187) --431 + j*(219) --304 + j*(-148) --4 + j*(-105) --141 + j*(-92) -194 + j*(-172) --30 + j*(-248) --45 + j*(157) --4 + j*(109) -170 + j*(193) -153 + j*(-243) --304 + j*(-82) -92 + j*(64) -76 + j*(16) -68 + j*(46) --146 + j*(144) -219 + j*(222) --216 + j*(68) --88 + j*(-248) --170 + j*(42) -79 + j*(-355) -43 + j*(67) -69 + j*(33) --137 + j*(-228) -72 + j*(132) --40 + j*(-29) --1 + j*(107) --73 + j*(333) -285 + j*(-302) -252 + j*(-49) -74 + j*(-91) --83 + j*(156) --304 + j*(321) -100 + j*(-276) --182 + j*(-174) --49 + j*(-325) -78 + j*(-262) --262 + j*(-26) -134 + j*(83) --112 + j*(83) -7 + j*(65) --11 + j*(110) -115 + j*(47) --45 + j*(-115) -1 + j*(-168) --112 + j*(-49) --293 + j*(28) --351 + j*(-62) --10 + j*(27) -226 + j*(-30) --57 + j*(176) -37 + j*(-181) -172 + j*(143) -187 + j*(248) --205 + j*(1) -187 + j*(-23) --280 + j*(-25) -200 + j*(-519) --30 + j*(218) --90 + j*(220) --58 + j*(22) -110 + j*(-327) --165 + j*(30) --2 + j*(-261) -222 + j*(-47) --115 + j*(-274) -284 + j*(65) -166 + j*(339) --2 + j*(192) --54 + j*(-168) -139 + j*(-147) -202 + j*(-148) --88 + j*(-42) --88 + j*(87) --16 + j*(-157) --116 + j*(-215) -254 + j*(57) --135 + j*(-27) -82 + j*(223) --165 + j*(206) -29 + j*(-119) --112 + j*(-28) -241 + j*(330) --164 + j*(-91) --162 + j*(-92) -39 + j*(57) --105 + j*(240) --96 + j*(-112) -266 + j*(274) -272 + j*(-71) --81 + j*(79) -100 + j*(-11) --52 + j*(-24) -325 + j*(-252) --24 + j*(363) -170 + j*(-103) --224 + j*(263) -229 + j*(123) -62 + j*(-281) --139 + j*(-92) --103 + j*(124) -387 + j*(-151) -103 + j*(252) --52 + j*(-88) -150 + j*(-183) --508 + j*(47) -16 + j*(-13) -40 + j*(104) --18 + j*(-61) -436 + j*(25) --60 + j*(-131) -165 + j*(101) -220 + j*(191) --254 + j*(-140) -21 + j*(-212) --81 + j*(-122) --252 + j*(-175) -11 + j*(124) --47 + j*(38) -163 + j*(227) --525 + j*(30) -117 + j*(453) --137 + j*(-71) -136 + j*(34) -127 + j*(26) --360 + j*(-185) -247 + j*(-28) --350 + j*(317) --262 + j*(151) -58 + j*(-221) --10 + j*(156) --387 + j*(64) --25 + j*(223) --42 + j*(110) -33 + j*(378) -35 + j*(90) --264 + j*(78) --112 + j*(109) -123 + j*(68) -276 + j*(-239) --11 + j*(-231) -416 + j*(23) -276 + j*(196) --52 + j*(-30) --125 + j*(6) -297 + j*(47) -186 + j*(-114) -75 + j*(-99) -379 + j*(1) --25 + j*(330) --81 + j*(-228) --118 + j*(-213) --45 + j*(-100) --372 + j*(84) --93 + j*(-155) --169 + j*(-9) -245 + j*(-222) --134 + j*(-5) --188 + j*(303) --162 + j*(-185) -132 + j*(-141) --325 + j*(301) --42 + j*(-164) -256 + j*(151) -52 + j*(69) --128 + j*(325) --165 + j*(134) --162 + j*(-32) --117 + j*(-190) -17 + j*(-82) -173 + j*(-173) -298 + j*(-11) --151 + j*(141) --327 + j*(147) --62 + j*(72) --21 + j*(-19) --10 + j*(-189) --36 + j*(50) -95 + j*(-60) -122 + j*(141) -125 + j*(23) -18 + j*(218) --36 + j*(288) --127 + j*(81) -21 + j*(-100) --216 + j*(-237) -85 + j*(-117) -4 + j*(-219) -260 + j*(-119) -154 + j*(132) --110 + j*(312) --231 + j*(91) -269 + j*(65) --62 + j*(-256) --133 + j*(-183) -84 + j*(-89) -143 + j*(-9) --245 + j*(11) --196 + j*(-218) -85 + j*(-211) --146 + j*(91) --179 + j*(-57) --122 + j*(-66) --112 + j*(45) --354 + j*(-65) -101 + j*(-99) -362 + j*(243) --141 + j*(-321) -210 + j*(114) -127 + j*(223) -257 + j*(-35) --298 + j*(63) --88 + j*(397) --272 + j*(72) -44 + j*(387) --170 + j*(-21) -60 + j*(104) --310 + j*(-85) --327 + j*(213) -326 + j*(-179) --96 + j*(-5) -15 + j*(-286) --76 + j*(27) -103 + j*(124) -5 + j*(-456) --133 + j*(-173) --7 + j*(-293) --62 + j*(-57) -93 + j*(-42) -282 + j*(-146) -133 + j*(252) --98 + j*(63) -14 + j*(138) --192 + j*(108) -100 + j*(216) --214 + j*(-267) -287 + j*(-177) -138 + j*(-223) --74 + j*(92) -210 + j*(134) --143 + j*(40) -119 + j*(-45) -115 + j*(30) -344 + j*(-255) -175 + j*(116) --238 + j*(98) --122 + j*(-103) --223 + j*(378) -213 + j*(103) -23 + j*(163) --150 + j*(130) -116 + j*(257) --257 + j*(-51) --151 + j*(-144) -98 + j*(-243) --285 + j*(-140) -171 + j*(347) -66 + j*(-49) -294 + j*(-273) --100 + j*(-174) --237 + j*(-134) --459 + j*(320) --73 + j*(2) -162 + j*(180) -64 + j*(-307) -263 + j*(-46) --95 + j*(-274) --50 + j*(103) -191 + j*(170) --107 + j*(60) -42 + j*(-159) --35 + j*(-46) --72 + j*(91) -341 + j*(-216) -112 + j*(249) --114 + j*(-213) -11 + j*(71) --42 + j*(-106) --70 + j*(-117) --204 + j*(-8) --30 + j*(59) --257 + j*(263) -190 + j*(-417) --6 + j*(152) --127 + j*(97) --64 + j*(99) --428 + j*(144) --178 + j*(-112) -539 + j*(-2) -338 + j*(-120) -108 + j*(-235) --324 + j*(-28) -16 + j*(160) -70 + j*(188) -11 + j*(73) --49 + j*(-291) -206 + j*(197) -237 + j*(136) -83 + j*(216) -54 + j*(-149) --28 + j*(-105) --37 + j*(-55) -132 + j*(-138) -138 + j*(-161) -55 + j*(-45) --99 + j*(168) -173 + j*(175) -7 + j*(49) --8 + j*(55) -93 + j*(248) -16 + j*(-199) --104 + j*(324) --163 + j*(122) -66 + j*(112) -134 + j*(-49) -25 + j*(-253) --76 + j*(-95) -42 + j*(245) -151 + j*(-187) --153 + j*(-282) -39 + j*(-135) -4 + j*(-163) -75 + j*(190) --126 + j*(-10) -171 + j*(55) --3 + j*(-19) --59 + j*(76) --189 + j*(-52) -125 + j*(-81) -254 + j*(-258) -25 + j*(-116) --359 + j*(333) --127 + j*(110) --243 + j*(156) -184 + j*(33) --265 + j*(5) --120 + j*(4) --265 + j*(-8) -168 + j*(-161) -65 + j*(125) --62 + j*(-164) --208 + j*(-21) --142 + j*(-322) --378 + j*(19) --73 + j*(76) --61 + j*(151) --141 + j*(-202) -132 + j*(133) -228 + j*(-25) -458 + j*(-65) --133 + j*(-45) --233 + j*(85) -126 + j*(-35) -81 + j*(-158) -239 + j*(64) -169 + j*(179) -23 + j*(318) --153 + j*(-144) -92 + j*(-21) -3 + j*(197) -31 + j*(52) -74 + j*(-50) -117 + j*(-38) --108 + j*(-49) -129 + j*(-19) --218 + j*(-81) -123 + j*(-25) -326 + j*(-124) --146 + j*(-104) --19 + j*(-156) --30 + j*(-185) -52 + j*(86) --529 + j*(6) -194 + j*(-97) -109 + j*(278) --315 + j*(-296) -241 + j*(168) -107 + j*(228) --103 + j*(219) -79 + j*(238) -91 + j*(-158) -343 + j*(-144) --165 + j*(-165) --375 + j*(49) -257 + j*(-81) -223 + j*(160) --144 + j*(-144) --11 + j*(252) -70 + j*(-40) -40 + j*(79) -400 + j*(191) -8 + j*(-76) --98 + j*(-105) -8 + j*(33) --69 + j*(-42) -270 + j*(-35) -23 + j*(22) --418 + j*(-221) --38 + j*(-53) -28 + j*(64) -114 + j*(291) -421 + j*(272) --222 + j*(250) --34 + j*(83) -119 + j*(-148) --141 + j*(136) --165 + j*(40) -110 + j*(-94) --341 + j*(105) --62 + j*(25) --187 + j*(107) --132 + j*(221) --17 + j*(1) -279 + j*(-247) -81 + j*(148) -46 + j*(116) --448 + j*(-277) --310 + j*(431) -30 + j*(28) -136 + j*(-87) -8 + j*(24) -257 + j*(-246) --8 + j*(165) --49 + j*(-32) --11 + j*(-11) -34 + j*(-10) --53 + j*(21) -361 + j*(103) --284 + j*(-36) --202 + j*(-190) -62 + j*(88) --69 + j*(190) --66 + j*(-338) -54 + j*(31) --71 + j*(105) --177 + j*(-55) -235 + j*(-53) -28 + j*(104) --363 + j*(80) -144 + j*(2) -250 + j*(192) --60 + j*(1) --206 + j*(-163) -54 + j*(-66) --91 + j*(-169) --78 + j*(-36) -91 + j*(-15) --30 + j*(107) -85 + j*(14) --285 + j*(21) -179 + j*(152) --197 + j*(-69) -86 + j*(-214) -200 + j*(158) -29 + j*(153) --181 + j*(-278) --89 + j*(-222) --172 + j*(-129) --30 + j*(272) -365 + j*(-10) --40 + j*(-85) --8 + j*(-57) --241 + j*(-301) --267 + j*(-530) -38 + j*(-85) --91 + j*(478) --18 + j*(-260) --261 + j*(-103) -41 + j*(69) -376 + j*(74) -59 + j*(342) --450 + j*(-386) --185 + j*(-6) -399 + j*(284) -69 + j*(128) --247 + j*(-365) -88 + j*(-74) -182 + j*(16) --257 + j*(209) --336 + j*(26) --260 + j*(-74) -80 + j*(66) --257 + j*(-243) -139 + j*(-35) --354 + j*(33) -21 + j*(-107) --279 + j*(46) --124 + j*(192) --474 + j*(-165) -61 + j*(-238) --114 + j*(182) --122 + j*(-105) --265 + j*(192) -209 + j*(-58) -134 + j*(-87) --124 + j*(-299) --112 + j*(196) -132 + j*(38) --180 + j*(303) --203 + j*(82) --62 + j*(-222) -37 + j*(371) -128 + j*(148) -194 + j*(198) -11 + j*(-93) -23 + j*(-392) --9 + j*(213) -284 + j*(-231) -108 + j*(-115) --86 + j*(-54) --78 + j*(25) --66 + j*(-118) -139 + j*(-135) -95 + j*(-66) --155 + j*(-134) --136 + j*(13) -37 + j*(147) -105 + j*(-52) -124 + j*(180) -93 + j*(129) -85 + j*(233) -139 + j*(-129) -363 + j*(93) -110 + j*(181) -321 + j*(-131) --116 + j*(-50) -292 + j*(52) -130 + j*(-219) --76 + j*(155) -170 + j*(8) --60 + j*(36) -105 + j*(58) -368 + j*(125) --136 + j*(-108) --142 + j*(69) -21 + j*(-49) -10 + j*(-94) --196 + j*(-4) -488 + j*(313) -86 + j*(-116) -167 + j*(34) --52 + j*(267) --132 + j*(273) --107 + j*(-311) -12 + j*(-185) -148 + j*(-227) --175 + j*(-88) -68 + j*(40) -44 + j*(-27) -158 + j*(-191) --6 + j*(122) -315 + j*(-21) --213 + j*(59) -421 + j*(-175) --81 + j*(275) --93 + j*(80) --29 + j*(-130) --58 + j*(153) --246 + j*(-158) -71 + j*(-250) --354 + j*(120) -37 + j*(195) -460 + j*(-35) --176 + j*(-60) -109 + j*(30) --274 + j*(46) -163 + j*(-293) -339 + j*(124) --288 + j*(103) -256 + j*(-101) --62 + j*(173) --130 + j*(288) -137 + j*(-49) -169 + j*(-1) --69 + j*(-170) --231 + j*(207) -165 + j*(62) --147 + j*(102) --28 + j*(158) --18 + j*(-250) -58 + j*(-124) --211 + j*(-76) --277 + j*(-126) --288 + j*(281) --47 + j*(91) -57 + j*(-258) -158 + j*(31) -173 + j*(-93) -64 + j*(-301) --178 + j*(88) --129 + j*(518) -144 + j*(-270) -146 + j*(-278) -239 + j*(122) -274 + j*(8) -77 + j*(-119) --47 + j*(-154) --2 + j*(219) --204 + j*(267) -118 + j*(166) -42 + j*(-456) --47 + j*(29) --187 + j*(180) --112 + j*(230) -95 + j*(-22) -120 + j*(381) -244 + j*(-168) --9 + j*(103) -143 + j*(97) --337 + j*(1) -228 + j*(18) --43 + j*(92) --42 + j*(6) --16 + j*(483) -35 + j*(257) -100 + j*(-82) -245 + j*(144) -136 + j*(-35) -167 + j*(31) --45 + j*(129) --165 + j*(130) -431 + j*(227) --163 + j*(-289) -157 + j*(-82) -371 + j*(-184) -8 + j*(117) --247 + j*(-31) -57 + j*(120) --107 + j*(-310) --71 + j*(-28) --234 + j*(-110) --88 + j*(80) --275 + j*(75) --202 + j*(311) --124 + j*(-170) -1 + j*(-284) --44 + j*(-331) --148 + j*(-53) --11 + j*(8) -156 + j*(255) -302 + j*(170) --139 + j*(47) -50 + j*(146) --132 + j*(234) --40 + j*(0) -31 + j*(-148) --151 + j*(64) -202 + j*(-64) -207 + j*(42) --194 + j*(48) -100 + j*(-102) -97 + j*(123) -262 + j*(82) --321 + j*(-168) --282 + j*(19) --35 + j*(201) -257 + j*(114) --47 + j*(-174) --59 + j*(-81) -1 + j*(-50) --180 + j*(-216) --141 + j*(-33) --106 + j*(167) -14 + j*(62) -151 + j*(104) --206 + j*(-145) -132 + j*(-35) --2 + j*(94) -107 + j*(101) -65 + j*(93) -30 + j*(-250) -175 + j*(159) -16 + j*(202) --87 + j*(-223) -7 + j*(-244) -58 + j*(-51) -103 + j*(-135) --168 + j*(-313) --325 + j*(132) --136 + j*(-111) --211 + j*(-162) -35 + j*(-76) -354 + j*(196) -132 + j*(-28) --12 + j*(-352) -140 + j*(-337) --144 + j*(-102) --115 + j*(-63) --36 + j*(65) --98 + j*(-89) --119 + j*(53) -91 + j*(-206) -51 + j*(-476) -160 + j*(-76) --222 + j*(-345) --265 + j*(202) -86 + j*(-40) -142 + j*(170) -115 + j*(237) -187 + j*(-6) --32 + j*(-87) --379 + j*(175) --46 + j*(-578) --116 + j*(-57) -30 + j*(19) --80 + j*(115) -13 + j*(100) --116 + j*(121) -30 + j*(237) --226 + j*(165) --220 + j*(-202) -70 + j*(-153) --282 + j*(-106) --322 + j*(-4) --46 + j*(7) -176 + j*(41) -195 + j*(132) --103 + j*(23) --114 + j*(-115) -153 + j*(317) --57 + j*(60) --160 + j*(-151) --236 + j*(167) -203 + j*(-55) --18 + j*(7) --244 + j*(-16) -250 + j*(159) -3 + j*(-170) --54 + j*(33) --42 + j*(-67) -334 + j*(149) --354 + j*(85) --4 + j*(-64) --63 + j*(92) -223 + j*(-244) -4 + j*(-47) -125 + j*(-204) -107 + j*(70) -191 + j*(-337) --331 + j*(185) --441 + j*(74) --96 + j*(178) --70 + j*(83) -152 + j*(100) --117 + j*(371) -184 + j*(-202) --223 + j*(200) --42 + j*(-50) -18 + j*(126) -20 + j*(-46) --298 + j*(203) -46 + j*(146) --153 + j*(-19) -268 + j*(-62) -103 + j*(-322) -157 + j*(694) --23 + j*(105) --129 + j*(183) --28 + j*(132) -21 + j*(37) -30 + j*(173) --101 + j*(121) --100 + j*(189) --272 + j*(-186) -211 + j*(-85) --222 + j*(-71) --218 + j*(-44) --98 + j*(38) -88 + j*(113) -249 + j*(-197) -86 + j*(346) --49 + j*(-60) -235 + j*(230) -62 + j*(-8) --169 + j*(-186) -304 + j*(-342) -119 + j*(65) -34 + j*(-357) -125 + j*(-96) --258 + j*(103) -71 + j*(-79) --179 + j*(193) --139 + j*(-187) --236 + j*(-131) -408 + j*(340) -139 + j*(-67) --29 + j*(21) --59 + j*(99) --19 + j*(-37) -377 + j*(107) --272 + j*(164) -81 + j*(-98) --44 + j*(-69) --203 + j*(-243) --63 + j*(116) --82 + j*(13) --4 + j*(-42) -83 + j*(-158) --216 + j*(-180) --112 + j*(112) --232 + j*(-168) -146 + j*(169) --199 + j*(55) -74 + j*(-52) --69 + j*(-372) --64 + j*(-177) --92 + j*(-14) -1 + j*(-285) --81 + j*(-277) -57 + j*(-180) --185 + j*(-419) --235 + j*(-25) --298 + j*(117) --20 + j*(82) -110 + j*(231) -20 + j*(-115) -223 + j*(71) --54 + j*(18) --82 + j*(-61) --54 + j*(88) -112 + j*(-132) --216 + j*(-183) -144 + j*(135) --95 + j*(361) -126 + j*(194) -4 + j*(-424) -185 + j*(91) --4 + j*(-30) --112 + j*(-177) --479 + j*(195) --301 + j*(-36) --324 + j*(74) -66 + j*(20) --174 + j*(-128) -57 + j*(-160) -1 + j*(-95) -121 + j*(-1) -78 + j*(-13) -8 + j*(-64) --83 + j*(46) --59 + j*(-35) -7 + j*(23) --100 + j*(168) --151 + j*(-72) --171 + j*(-166) -124 + j*(396) --94 + j*(-126) -136 + j*(-111) --80 + j*(-441) -136 + j*(268) -358 + j*(69) -11 + j*(-5) --298 + j*(-37) --37 + j*(144) --185 + j*(4) --16 + j*(282) --12 + j*(-115) --4 + j*(-86) -29 + j*(-469) --443 + j*(-96) --258 + j*(7) -115 + j*(-133) --213 + j*(-262) -279 + j*(-81) -129 + j*(-107) --167 + j*(38) --91 + j*(-312) --202 + j*(335) -262 + j*(37) -1 + j*(-13) -135 + j*(319) -127 + j*(297) -130 + j*(115) --280 + j*(151) --213 + j*(-125) --90 + j*(23) -110 + j*(192) --148 + j*(-175) --91 + j*(-89) -428 + j*(-33) -122 + j*(-108) -206 + j*(-93) --56 + j*(-170) -330 + j*(-283) -243 + j*(18) -257 + j*(-235) -95 + j*(-140) --50 + j*(-323) --146 + j*(214) -167 + j*(229) --22 + j*(23) -72 + j*(-136) -265 + j*(-286) --305 + j*(-121) -6 + j*(165) -124 + j*(-304) -184 + j*(78) -360 + j*(8) --103 + j*(-96) -99 + j*(-48) --266 + j*(145) -206 + j*(-59) -313 + j*(58) --79 + j*(-182) -109 + j*(91) --360 + j*(-320) -153 + j*(227) --165 + j*(87) -34 + j*(-18) -3 + j*(229) -1 + j*(49) -245 + j*(140) --162 + j*(89) --110 + j*(-125) --93 + j*(202) -109 + j*(-93) -90 + j*(-56) -358 + j*(151) -286 + j*(-158) -182 + j*(-62) --204 + j*(49) -20 + j*(279) --105 + j*(-283) --83 + j*(43) --13 + j*(-51) --68 + j*(176) --152 + j*(-12) --129 + j*(231) -9 + j*(143) -102 + j*(-153) --134 + j*(-113) -34 + j*(174) --151 + j*(180) --45 + j*(-171) -206 + j*(-89) -154 + j*(144) --146 + j*(-276) -216 + j*(57) -495 + j*(30) --177 + j*(25) -97 + j*(240) --84 + j*(-176) --194 + j*(-102) -33 + j*(-204) -181 + j*(-70) --52 + j*(280) -47 + j*(64) --77 + j*(67) -408 + j*(27) -171 + j*(74) --318 + j*(177) -98 + j*(136) --166 + j*(124) -21 + j*(223) --105 + j*(143) --185 + j*(162) -11 + j*(6) -218 + j*(118) --149 + j*(190) -42 + j*(121) --117 + j*(100) --86 + j*(32) -13 + j*(-127) -13 + j*(-260) -102 + j*(49) -173 + j*(210) -110 + j*(-64) --13 + j*(329) -145 + j*(-61) -44 + j*(-65) --110 + j*(-280) -226 + j*(-64) -207 + j*(205) --9 + j*(-98) --291 + j*(-194) -59 + j*(129) --104 + j*(-78) -13 + j*(-115) -2 + j*(-84) -47 + j*(-117) --182 + j*(-156) -371 + j*(66) --185 + j*(249) --360 + j*(-141) -74 + j*(-243) -150 + j*(412) -293 + j*(13) -161 + j*(-319) --52 + j*(250) --81 + j*(-110) -35 + j*(25) -62 + j*(146) --134 + j*(-8) --101 + j*(64) --213 + j*(206) -49 + j*(27) --9 + j*(44) --30 + j*(57) --185 + j*(-103) --175 + j*(-29) --315 + j*(127) -294 + j*(-68) --98 + j*(390) -76 + j*(-11) -216 + j*(272) --136 + j*(5) -44 + j*(210) --3 + j*(-24) -182 + j*(-110) --61 + j*(40) --28 + j*(52) --95 + j*(-206) --57 + j*(230) -182 + j*(-40) -128 + j*(-143) -102 + j*(-54) --83 + j*(28) --37 + j*(-208) --220 + j*(183) -158 + j*(-382) -88 + j*(-19) --25 + j*(-37) -75 + j*(60) --63 + j*(-173) --230 + j*(-128) -112 + j*(-43) --158 + j*(-47) -20 + j*(49) --145 + j*(71) --297 + j*(68) --329 + j*(-21) -245 + j*(-95) --303 + j*(88) --72 + j*(151) --126 + j*(-173) -11 + j*(199) -127 + j*(423) -213 + j*(-18) -230 + j*(17) --110 + j*(-47) -347 + j*(166) -165 + j*(46) --402 + j*(100) --34 + j*(-164) -18 + j*(187) --27 + j*(102) -100 + j*(324) --43 + j*(-269) -118 + j*(-268) --69 + j*(187) -192 + j*(-211) -99 + j*(-127) -262 + j*(42) --93 + j*(-35) --245 + j*(-249) --39 + j*(-274) -115 + j*(-197) -179 + j*(8) -395 + j*(33) -324 + j*(-6) --129 + j*(105) -72 + j*(-66) --239 + j*(-16) --112 + j*(189) --334 + j*(-83) -91 + j*(235) --139 + j*(91) --136 + j*(122) -47 + j*(-132) -453 + j*(-16) --150 + j*(-126) --255 + j*(86) -146 + j*(-169) --31 + j*(158) -98 + j*(132) --260 + j*(86) --20 + j*(145) -77 + j*(-175) --227 + j*(271) --25 + j*(115) -76 + j*(267) --192 + j*(66) --274 + j*(-34) --163 + j*(-132) --155 + j*(-195) -91 + j*(46) --137 + j*(-191) --151 + j*(260) --8 + j*(29) --83 + j*(25) -17 + j*(-16) --430 + j*(494) -212 + j*(55) -134 + j*(86) -188 + j*(-2) --11 + j*(151) -209 + j*(27) --37 + j*(40) --202 + j*(90) --25 + j*(327) -81 + j*(-401) --180 + j*(194) --146 + j*(262) -221 + j*(87) -280 + j*(-118) --30 + j*(15) -164 + j*(91) -45 + j*(-315) --325 + j*(43) --283 + j*(-286) --63 + j*(-174) --220 + j*(-100) -190 + j*(-108) -37 + j*(-11) -148 + j*(-88) --103 + j*(-93) -122 + j*(94) --124 + j*(-273) --59 + j*(-193) -13 + j*(77) -3 + j*(-186) -36 + j*(-62) --219 + j*(232) -103 + j*(71) -54 + j*(47) -13 + j*(52) --356 + j*(119) --124 + j*(152) -77 + j*(33) --83 + j*(148) --40 + j*(-25) -35 + j*(-64) --170 + j*(-244) --301 + j*(-208) --61 + j*(140) --197 + j*(-47) --134 + j*(-243) -34 + j*(269) --169 + j*(-330) -65 + j*(46) -167 + j*(47) --118 + j*(-40) -65 + j*(-15) --16 + j*(211) --63 + j*(107) -50 + j*(120) --194 + j*(9) --97 + j*(90) --226 + j*(-82) -59 + j*(-375) -123 + j*(-107) -112 + j*(63) --95 + j*(146) --209 + j*(91) -278 + j*(-85) -190 + j*(134) -296 + j*(-10) --175 + j*(-175) -136 + j*(-52) -166 + j*(-25) -129 + j*(107) --254 + j*(-54) -132 + j*(6) -137 + j*(95) --457 + j*(-166) --146 + j*(34) --46 + j*(-144) -32 + j*(291) -143 + j*(168) -108 + j*(14) -25 + j*(-109) --262 + j*(148) --111 + j*(-62) -170 + j*(-84) --148 + j*(217) --279 + j*(-161) --50 + j*(-172) -261 + j*(-89) --186 + j*(31) --35 + j*(201) --392 + j*(-57) --43 + j*(291) --125 + j*(65) -157 + j*(-12) --43 + j*(40) -173 + j*(-97) -231 + j*(-39) -40 + j*(-25) --184 + j*(-57) -31 + j*(-173) --262 + j*(74) -6 + j*(214) -37 + j*(-114) --296 + j*(-238) -115 + j*(-8) -17 + j*(-50) --165 + j*(134) --115 + j*(127) --419 + j*(-182) --29 + j*(-102) -49 + j*(348) --173 + j*(-4) --431 + j*(31) --60 + j*(21) --130 + j*(-76) --278 + j*(-74) --156 + j*(-45) -383 + j*(187) -241 + j*(-255) -105 + j*(-116) --6 + j*(-184) -327 + j*(-173) --32 + j*(39) -23 + j*(78) -35 + j*(0) -116 + j*(-264) --10 + j*(-5) --44 + j*(110) --103 + j*(-112) --506 + j*(227) -144 + j*(-71) -150 + j*(43) -45 + j*(344) --286 + j*(-126) -24 + j*(-301) --136 + j*(-288) -23 + j*(-66) --247 + j*(-122) -2 + j*(-254) --434 + j*(-101) --262 + j*(86) --265 + j*(-110) --293 + j*(115) --11 + j*(361) -249 + j*(-121) --88 + j*(35) --232 + j*(-86) -296 + j*(8) --125 + j*(4) --14 + j*(-228) --212 + j*(259) -30 + j*(207) -165 + j*(-69) -454 + j*(0) --282 + j*(71) -41 + j*(-194) -264 + j*(-13) --313 + j*(129) -82 + j*(106) -76 + j*(-2) -245 + j*(-102) --92 + j*(245) -242 + j*(-47) --132 + j*(-83) -231 + j*(-56) --64 + j*(-59) --94 + j*(-115) -241 + j*(154) --261 + j*(-173) --56 + j*(157) --54 + j*(-21) --180 + j*(28) -144 + j*(104) -64 + j*(23) --93 + j*(-354) -189 + j*(185) --110 + j*(-22) -209 + j*(-222) -79 + j*(-39) -217 + j*(-105) --21 + j*(-139) -91 + j*(205) -195 + j*(-93) --6 + j*(-144) --231 + j*(117) --18 + j*(-35) -87 + j*(190) -152 + j*(56) -248 + j*(66) --3 + j*(-235) --81 + j*(132) --59 + j*(315) --289 + j*(142) -100 + j*(-118) --191 + j*(355) -52 + j*(-271) -1 + j*(-161) --151 + j*(-81) -198 + j*(357) --202 + j*(-13) -19 + j*(-220) -188 + j*(-258) -90 + j*(105) --168 + j*(25) -37 + j*(-505) -281 + j*(-93) --241 + j*(-156) -49 + j*(-28) -16 + j*(-299) -151 + j*(-229) --42 + j*(136) --228 + j*(43) --124 + j*(148) --7 + j*(19) -250 + j*(-66) -207 + j*(118) -80 + j*(28) --22 + j*(61) -190 + j*(-61) -206 + j*(-161) -27 + j*(-344) --176 + j*(-18) -233 + j*(-76) -64 + j*(-87) -334 + j*(-81) -216 + j*(-3) -1 + j*(499) -57 + j*(-66) --123 + j*(-246) --329 + j*(-81) --113 + j*(-94) -41 + j*(204) --194 + j*(-10) --52 + j*(116) --80 + j*(33) --271 + j*(-388) --288 + j*(-45) --65 + j*(-40) -118 + j*(-59) -296 + j*(-220) --175 + j*(57) -4 + j*(71) --124 + j*(62) -153 + j*(95) -209 + j*(209) -132 + j*(293) --72 + j*(-90) -378 + j*(3) -57 + j*(266) --354 + j*(42) -84 + j*(-270) --52 + j*(303) -211 + j*(-53) -132 + j*(-156) -375 + j*(37) --21 + j*(87) -381 + j*(-107) -86 + j*(-33) -98 + j*(21) --189 + j*(-212) --138 + j*(-247) -330 + j*(-127) -34 + j*(-63) -181 + j*(139) --86 + j*(144) -206 + j*(-378) -165 + j*(29) --133 + j*(183) -52 + j*(-56) --140 + j*(123) --123 + j*(68) --13 + j*(243) --144 + j*(-129) --265 + j*(-195) -148 + j*(139) -117 + j*(-42) --105 + j*(-67) --64 + j*(-123) -20 + j*(-232) --250 + j*(85) --117 + j*(-41) --474 + j*(269) -76 + j*(-93) -23 + j*(-175) --138 + j*(191) -13 + j*(-97) -15 + j*(395) -71 + j*(56) --91 + j*(74) --180 + j*(134) --23 + j*(90) -110 + j*(313) --309 + j*(-167) -13 + j*(44) -146 + j*(276) -105 + j*(-266) --9 + j*(-158) -69 + j*(-4) --45 + j*(-214) -148 + j*(69) -95 + j*(98) -322 + j*(-187) --102 + j*(-109) --287 + j*(66) --108 + j*(-247) -62 + j*(112) -86 + j*(-119) -75 + j*(65) --5 + j*(192) --112 + j*(0) -301 + j*(-56) --206 + j*(83) --30 + j*(192) --293 + j*(-1) -167 + j*(98) -144 + j*(-275) -76 + j*(80) --81 + j*(314) --132 + j*(-187) --124 + j*(-295) --412 + j*(339) -49 + j*(-5) --10 + j*(-172) --36 + j*(-47) --112 + j*(-105) -171 + j*(441) --104 + j*(-93) -128 + j*(211) --76 + j*(-84) -84 + j*(350) -47 + j*(-100) --137 + j*(-182) --22 + j*(-212) -8 + j*(100) --58 + j*(252) -55 + j*(40) --95 + j*(127) -252 + j*(-148) --147 + j*(-35) -202 + j*(-465) -127 + j*(-109) --136 + j*(-75) -122 + j*(67) -34 + j*(-97) --622 + j*(-2) -240 + j*(49) -230 + j*(95) --16 + j*(33) -129 + j*(178) --92 + j*(131) --146 + j*(-288) --11 + j*(-154) -243 + j*(-119) --293 + j*(-419) -12 + j*(146) -11 + j*(258) --267 + j*(-30) -378 + j*(180) --145 + j*(-53) --152 + j*(-247) --127 + j*(-30) -244 + j*(-144) --57 + j*(107) -324 + j*(203) -158 + j*(-66) -308 + j*(-268) -119 + j*(-105) --98 + j*(127) --189 + j*(-178) --35 + j*(-40) -142 + j*(378) --226 + j*(-28) -273 + j*(-14) -65 + j*(-8) --95 + j*(-134) --35 + j*(83) -49 + j*(157) --52 + j*(-219) -14 + j*(280) --33 + j*(-86) -86 + j*(-61) --508 + j*(-100) -161 + j*(-415) --86 + j*(-105) -65 + j*(-98) -233 + j*(69) --90 + j*(115) -47 + j*(171) --141 + j*(-136) -70 + j*(-102) --40 + j*(-204) --239 + j*(-93) -192 + j*(155) --231 + j*(32) --45 + j*(-419) -20 + j*(-41) -7 + j*(42) -258 + j*(-222) -98 + j*(-2) --13 + j*(62) --309 + j*(-131) -158 + j*(96) --309 + j*(-138) --322 + j*(-272) -168 + j*(-258) --395 + j*(131) -187 + j*(-576) --81 + j*(-438) --147 + j*(-62) --220 + j*(-71) --203 + j*(-38) -184 + j*(113) -0 + j*(-317) -167 + j*(-6) --226 + j*(78) --146 + j*(-158) --223 + j*(21) --170 + j*(70) -21 + j*(-109) --54 + j*(103) -407 + j*(-218) --4 + j*(-20) -207 + j*(-315) --80 + j*(-86) -180 + j*(-165) --144 + j*(289) -146 + j*(262) -38 + j*(-47) -352 + j*(281) -290 + j*(-41) --28 + j*(-112) -38 + j*(323) --56 + j*(-105) --68 + j*(74) -249 + j*(117) -13 + j*(223) --66 + j*(356) --146 + j*(-142) --55 + j*(216) -181 + j*(215) -252 + j*(74) -143 + j*(-118) -93 + j*(125) -29 + j*(22) --83 + j*(-94) -66 + j*(21) --62 + j*(146) -264 + j*(-65) --211 + j*(389) --119 + j*(245) -24 + j*(-66) -71 + j*(22) --1 + j*(-225) -80 + j*(-397) --206 + j*(-12) --6 + j*(158) -87 + j*(251) --8 + j*(139) --56 + j*(126) --327 + j*(45) -37 + j*(-74) --45 + j*(381) -94 + j*(-11) --6 + j*(46) --115 + j*(-161) -171 + j*(-400) --3 + j*(44) --228 + j*(208) --20 + j*(-47) --117 + j*(-197) --104 + j*(89) -102 + j*(-254) -76 + j*(-246) --368 + j*(-77) -49 + j*(107) -47 + j*(53) -87 + j*(-298) -199 + j*(-163) -116 + j*(-85) -25 + j*(-167) --1 + j*(74) --2 + j*(-13) -54 + j*(-91) -76 + j*(-262) -72 + j*(-146) --135 + j*(-182) -6 + j*(-18) --217 + j*(178) --46 + j*(69) --9 + j*(-42) --65 + j*(-80) --28 + j*(-10) --97 + j*(-62) -158 + j*(-168) -106 + j*(2) --184 + j*(-18) --233 + j*(16) -158 + j*(294) --172 + j*(-383) --199 + j*(-178) -125 + j*(-46) --41 + j*(17) --365 + j*(247) -262 + j*(-253) --105 + j*(72) --32 + j*(141) --2 + j*(-19) -143 + j*(-65) -42 + j*(125) -37 + j*(-173) -123 + j*(47) -45 + j*(-98) --40 + j*(143) -28 + j*(-257) -97 + j*(-254) -170 + j*(-148) --200 + j*(-47) --126 + j*(158) --278 + j*(21) -124 + j*(130) --147 + j*(-42) -8 + j*(200) --85 + j*(-76) -237 + j*(37) --167 + j*(184) -175 + j*(235) --180 + j*(380) --506 + j*(-137) --172 + j*(148) --28 + j*(23) -18 + j*(-223) --82 + j*(166) -11 + j*(121) -83 + j*(216) --210 + j*(-182) --269 + j*(99) -333 + j*(-19) --129 + j*(-68) -281 + j*(-123) --8 + j*(-74) --146 + j*(36) -91 + j*(-126) --94 + j*(45) --42 + j*(-46) -62 + j*(464) -89 + j*(-21) --281 + j*(67) -101 + j*(-325) -40 + j*(270) --163 + j*(107) --337 + j*(-230) --49 + j*(-117) -94 + j*(200) --100 + j*(119) --252 + j*(49) -164 + j*(40) -337 + j*(72) --47 + j*(-204) --224 + j*(-218) --180 + j*(218) -1 + j*(221) -221 + j*(-285) -259 + j*(-113) --71 + j*(366) --113 + j*(-133) -59 + j*(-132) -82 + j*(-6) --69 + j*(21) --182 + j*(-43) --27 + j*(-281) -80 + j*(-69) --54 + j*(-49) -91 + j*(-78) -214 + j*(-64) --216 + j*(246) --180 + j*(11) -81 + j*(-48) --34 + j*(-7) --8 + j*(57) --26 + j*(45) --324 + j*(264) -185 + j*(-170) --119 + j*(-197) -28 + j*(132) -16 + j*(67) -403 + j*(142) -152 + j*(152) --22 + j*(388) -44 + j*(0) -42 + j*(11) -35 + j*(-54) -182 + j*(-73) -153 + j*(-13) -159 + j*(-34) -316 + j*(83) -289 + j*(194) --134 + j*(-163) -87 + j*(117) -95 + j*(-318) -108 + j*(-79) --322 + j*(431) --1 + j*(314) -69 + j*(-359) -117 + j*(-21) --343 + j*(198) --25 + j*(-99) --10 + j*(-103) --76 + j*(182) --164 + j*(-390) --95 + j*(40) --181 + j*(182) --129 + j*(-161) --130 + j*(111) --20 + j*(1) --223 + j*(49) --129 + j*(119) --90 + j*(-31) -163 + j*(-215) --130 + j*(-217) -111 + j*(30) -40 + j*(63) --132 + j*(1) --240 + j*(-94) -301 + j*(-80) --62 + j*(-7) -85 + j*(-55) -144 + j*(4) --60 + j*(11) --43 + j*(-144) --178 + j*(136) -125 + j*(133) --44 + j*(124) -41 + j*(190) -75 + j*(223) --161 + j*(-218) -131 + j*(7) -21 + j*(102) --467 + j*(-260) -250 + j*(-82) -99 + j*(83) --223 + j*(349) --216 + j*(-151) -129 + j*(-349) -243 + j*(-324) -178 + j*(52) -194 + j*(-74) -146 + j*(200) -136 + j*(43) --378 + j*(-235) --290 + j*(151) -407 + j*(159) --139 + j*(-40) -130 + j*(-59) -135 + j*(353) -89 + j*(100) --30 + j*(-180) --50 + j*(-217) -76 + j*(-12) --197 + j*(-5) --296 + j*(0) --256 + j*(119) -233 + j*(-107) -16 + j*(-327) --274 + j*(325) -91 + j*(24) -47 + j*(-30) -211 + j*(-159) -277 + j*(18) -138 + j*(3) --142 + j*(-59) -212 + j*(-37) -97 + j*(382) -381 + j*(126) -221 + j*(-418) -328 + j*(-99) --93 + j*(-224) --30 + j*(-151) --246 + j*(-29) -230 + j*(13) -97 + j*(242) -8 + j*(-52) --58 + j*(141) -33 + j*(-67) --415 + j*(-201) --23 + j*(-113) --18 + j*(-187) -245 + j*(-151) -69 + j*(-96) --143 + j*(117) -179 + j*(47) -87 + j*(-223) --263 + j*(-198) --29 + j*(-86) -287 + j*(158) --59 + j*(113) -184 + j*(95) -264 + j*(42) --146 + j*(232) --67 + j*(-57) -19 + j*(-152) -187 + j*(182) --253 + j*(-218) -134 + j*(207) -91 + j*(-161) -131 + j*(-104) -132 + j*(-75) -95 + j*(427) --11 + j*(-45) --13 + j*(-20) --47 + j*(227) -86 + j*(66) -94 + j*(-35) --11 + j*(-71) --160 + j*(56) -36 + j*(255) -276 + j*(-119) -49 + j*(108) --98 + j*(-81) --76 + j*(-313) -240 + j*(4) --160 + j*(21) -8 + j*(-165) --163 + j*(261) --270 + j*(-73) -187 + j*(110) --86 + j*(-165) -214 + j*(134) --33 + j*(-112) --421 + j*(278) -19 + j*(46) -53 + j*(228) --442 + j*(-151) -69 + j*(59) --86 + j*(55) -50 + j*(-371) --199 + j*(113) --13 + j*(172) -168 + j*(52) -384 + j*(291) --89 + j*(-129) --343 + j*(-387) --37 + j*(300) --37 + j*(-66) --209 + j*(-116) -112 + j*(2) -87 + j*(-80) --272 + j*(-38) --51 + j*(40) --221 + j*(-138) --182 + j*(-378) --461 + j*(-30) --141 + j*(-149) -269 + j*(-55) -122 + j*(68) -122 + j*(33) --153 + j*(-116) --47 + j*(-1) -285 + j*(30) -102 + j*(-137) -50 + j*(-193) --409 + j*(-35) --162 + j*(171) -354 + j*(41) --216 + j*(101) -33 + j*(256) --114 + j*(203) --353 + j*(-30) -42 + j*(-177) --2 + j*(95) --100 + j*(-156) --117 + j*(-155) --144 + j*(-4) --138 + j*(-194) -33 + j*(-209) --113 + j*(6) --361 + j*(190) -153 + j*(-317) --49 + j*(81) --70 + j*(-52) -104 + j*(-284) -131 + j*(113) -28 + j*(6) -18 + j*(71) -47 + j*(100) -126 + j*(-6) --138 + j*(199) -18 + j*(-209) -158 + j*(-37) -237 + j*(-211) -277 + j*(-17) -87 + j*(151) --173 + j*(-153) -147 + j*(-314) --79 + j*(247) -128 + j*(-87) -26 + j*(-173) -236 + j*(-258) --177 + j*(25) --112 + j*(-148) --136 + j*(-163) --16 + j*(-223) --124 + j*(218) --49 + j*(-257) --156 + j*(-51) --25 + j*(-276) -88 + j*(1) --191 + j*(-42) --81 + j*(-92) -138 + j*(419) -2 + j*(88) --1 + j*(84) -119 + j*(194) --129 + j*(-187) --151 + j*(-66) --141 + j*(11) -107 + j*(-457) -256 + j*(140) -1 + j*(218) -130 + j*(134) -122 + j*(62) -96 + j*(-102) -72 + j*(-88) -59 + j*(-168) --111 + j*(-354) -189 + j*(-89) -224 + j*(-129) --127 + j*(88) -1 + j*(357) -139 + j*(163) -147 + j*(244) -100 + j*(94) -269 + j*(6) -13 + j*(-315) -71 + j*(-104) --110 + j*(30) -18 + j*(-172) --40 + j*(-19) --182 + j*(307) -129 + j*(344) --29 + j*(-144) --138 + j*(-13) -361 + j*(-96) --143 + j*(105) --92 + j*(-118) -16 + j*(52) --119 + j*(187) -296 + j*(-150) --188 + j*(-91) --7 + j*(-250) -83 + j*(-74) --110 + j*(113) --170 + j*(331) --52 + j*(-16) -97 + j*(-301) --269 + j*(-31) --89 + j*(69) -84 + j*(-25) -161 + j*(-239) --80 + j*(156) -148 + j*(-129) -191 + j*(196) --153 + j*(43) --117 + j*(-74) --46 + j*(-340) --41 + j*(-180) -53 + j*(-113) -182 + j*(195) -208 + j*(221) -6 + j*(14) -144 + j*(73) --83 + j*(-97) -30 + j*(223) --98 + j*(-148) --493 + j*(-247) --386 + j*(32) --112 + j*(326) -41 + j*(-60) -155 + j*(-324) -42 + j*(-76) --39 + j*(-154) -123 + j*(409) --132 + j*(-122) -209 + j*(-33) --313 + j*(55) -235 + j*(189) --382 + j*(339) -87 + j*(-11) -101 + j*(1) -186 + j*(-173) -23 + j*(-135) -427 + j*(74) -280 + j*(-122) --69 + j*(-35) -247 + j*(-23) -112 + j*(-204) -110 + j*(-6) --303 + j*(14) -245 + j*(250) --73 + j*(-16) -35 + j*(123) -49 + j*(49) --154 + j*(-42) --281 + j*(-35) --308 + j*(151) -151 + j*(22) -45 + j*(-136) --244 + j*(-184) --175 + j*(-62) -38 + j*(231) -6 + j*(98) --51 + j*(-29) --168 + j*(-286) -60 + j*(-317) -53 + j*(221) --120 + j*(98) --54 + j*(-115) -93 + j*(-67) -139 + j*(57) --66 + j*(108) --183 + j*(54) --59 + j*(-28) --165 + j*(35) --184 + j*(29) --275 + j*(165) -377 + j*(17) --283 + j*(-351) -42 + j*(141) -90 + j*(-40) --74 + j*(-148) -53 + j*(353) -4 + j*(-133) -440 + j*(-84) --33 + j*(113) -83 + j*(76) --175 + j*(-44) -69 + j*(-90) -103 + j*(135) -156 + j*(92) --122 + j*(-37) -48 + j*(-104) -250 + j*(-129) -88 + j*(190) --170 + j*(335) --293 + j*(20) -40 + j*(-365) -140 + j*(-265) -340 + j*(49) --47 + j*(135) -330 + j*(-47) --25 + j*(-161) --59 + j*(112) -185 + j*(186) -125 + j*(-295) --45 + j*(554) -100 + j*(13) -52 + j*(40) --13 + j*(-54) --218 + j*(-153) -11 + j*(-43) --39 + j*(3) -10 + j*(-15) --298 + j*(9) -123 + j*(-210) -179 + j*(-168) -211 + j*(-169) -250 + j*(216) -74 + j*(-95) --288 + j*(59) --35 + j*(135) -23 + j*(127) --22 + j*(190) --76 + j*(-112) -180 + j*(-251) -226 + j*(-145) -30 + j*(37) -79 + j*(137) -83 + j*(-292) -209 + j*(-6) --307 + j*(-122) -119 + j*(-90) -26 + j*(-105) --28 + j*(-279) --95 + j*(-34) --57 + j*(-282) --361 + j*(-175) --83 + j*(-77) --74 + j*(16) -370 + j*(52) --276 + j*(-269) -285 + j*(-62) --129 + j*(-197) --21 + j*(-14) --3 + j*(45) -371 + j*(43) --213 + j*(-98) -196 + j*(23) -187 + j*(62) --165 + j*(173) -61 + j*(-60) -194 + j*(-329) --269 + j*(-18) -160 + j*(-72) -62 + j*(284) -47 + j*(-228) --74 + j*(294) -64 + j*(78) -37 + j*(-100) --81 + j*(50) -18 + j*(-113) -157 + j*(217) -188 + j*(355) -37 + j*(-31) -176 + j*(-282) -190 + j*(28) -81 + j*(-1) --202 + j*(311) --52 + j*(120) --18 + j*(17) --330 + j*(-110) --84 + j*(472) -51 + j*(234) --144 + j*(366) --25 + j*(12) --69 + j*(-14) -540 + j*(-155) -52 + j*(81) -174 + j*(-171) -117 + j*(-86) --15 + j*(-315) -154 + j*(135) -107 + j*(97) --119 + j*(-209) -67 + j*(-233) -14 + j*(58) --94 + j*(159) --81 + j*(1) -107 + j*(-90) --29 + j*(38) --565 + j*(-190) --35 + j*(36) -255 + j*(220) --25 + j*(18) --337 + j*(-27) -89 + j*(-148) --89 + j*(-141) --12 + j*(20) -69 + j*(-27) -228 + j*(-64) -112 + j*(-27) --181 + j*(81) --102 + j*(-2) -61 + j*(257) --170 + j*(8) --4 + j*(-171) --119 + j*(-27) --156 + j*(10) -315 + j*(-231) -264 + j*(260) --37 + j*(129) -69 + j*(-72) -121 + j*(146) --37 + j*(221) --195 + j*(1) -301 + j*(107) -221 + j*(16) --313 + j*(-181) --51 + j*(-94) -140 + j*(-295) -6 + j*(-176) --135 + j*(4) --49 + j*(355) -87 + j*(69) --40 + j*(-108) -81 + j*(187) -51 + j*(-194) --98 + j*(175) --280 + j*(127) -194 + j*(-100) --287 + j*(185) --28 + j*(14) -57 + j*(55) --313 + j*(-42) -175 + j*(-13) --138 + j*(136) --7 + j*(27) -16 + j*(214) --4 + j*(70) --28 + j*(-166) --91 + j*(214) --64 + j*(-305) -293 + j*(-61) -268 + j*(182) -153 + j*(23) --50 + j*(-63) -57 + j*(-17) --127 + j*(47) --107 + j*(-67) -68 + j*(83) -38 + j*(-78) --169 + j*(-76) -132 + j*(134) -202 + j*(197) --224 + j*(140) --37 + j*(643) --233 + j*(16) --227 + j*(-88) --168 + j*(-213) -63 + j*(-224) -88 + j*(28) -8 + j*(165) --273 + j*(-146) --140 + j*(-8) --100 + j*(13) --232 + j*(1) --223 + j*(93) --132 + j*(-45) --20 + j*(248) -156 + j*(-44) -74 + j*(-89) -88 + j*(26) -161 + j*(-94) --11 + j*(-143) --145 + j*(124) --33 + j*(30) -485 + j*(173) -249 + j*(-310) --246 + j*(164) --104 + j*(134) --126 + j*(184) --135 + j*(259) -18 + j*(79) --115 + j*(67) --190 + j*(-126) --159 + j*(183) -184 + j*(-190) -390 + j*(-129) --35 + j*(-129) -342 + j*(363) -110 + j*(-233) -158 + j*(-269) -15 + j*(-55) --204 + j*(-508) -11 + j*(165) --346 + j*(-145) --168 + j*(75) --175 + j*(-120) --25 + j*(294) --119 + j*(337) --119 + j*(111) -11 + j*(-257) --141 + j*(-127) -116 + j*(57) --173 + j*(30) --138 + j*(68) --71 + j*(-35) -14 + j*(250) --11 + j*(-57) -57 + j*(-279) -74 + j*(274) --81 + j*(64) --378 + j*(-80) --279 + j*(211) --79 + j*(194) --6 + j*(261) -156 + j*(-58) --8 + j*(-139) -239 + j*(-23) --117 + j*(-64) --107 + j*(41) --198 + j*(-283) --91 + j*(-135) --43 + j*(-13) -99 + j*(30) -4 + j*(105) --276 + j*(319) --298 + j*(-84) --7 + j*(-237) --286 + j*(9) -74 + j*(122) -10 + j*(344) --185 + j*(161) -139 + j*(187) --332 + j*(-48) --35 + j*(-204) --7 + j*(-144) --6 + j*(266) -78 + j*(25) -37 + j*(78) -96 + j*(183) --107 + j*(-141) -66 + j*(-433) --127 + j*(-27) --96 + j*(138) --1 + j*(-129) --351 + j*(71) --324 + j*(202) --93 + j*(-97) -73 + j*(153) -115 + j*(-252) -156 + j*(172) --312 + j*(-143) --336 + j*(-115) --119 + j*(-85) -47 + j*(-141) -300 + j*(174) --219 + j*(57) -102 + j*(-172) -45 + j*(390) -17 + j*(-127) -31 + j*(135) -344 + j*(83) --76 + j*(140) -53 + j*(57) -199 + j*(192) --69 + j*(165) -5 + j*(216) -525 + j*(152) --233 + j*(-83) --221 + j*(283) -50 + j*(12) -214 + j*(-559) --118 + j*(-131) --77 + j*(-31) --30 + j*(-192) -130 + j*(-141) -215 + j*(296) --64 + j*(65) -209 + j*(-41) -81 + j*(219) --110 + j*(-412) -119 + j*(130) -199 + j*(-42) -72 + j*(-13) --223 + j*(53) -45 + j*(28) -262 + j*(-16) -11 + j*(78) -182 + j*(-139) -73 + j*(211) -183 + j*(11) --7 + j*(171) -65 + j*(-11) --12 + j*(-45) -10 + j*(251) -110 + j*(-240) -187 + j*(-95) --42 + j*(-128) -26 + j*(117) --77 + j*(128) --45 + j*(70) -74 + j*(-117) --28 + j*(109) --175 + j*(-98) -119 + j*(204) -8 + j*(298) --43 + j*(-71) -105 + j*(107) --46 + j*(31) --23 + j*(-230) --141 + j*(-225) --245 + j*(-98) --115 + j*(-24) -52 + j*(330) --5 + j*(218) --179 + j*(37) -50 + j*(52) -40 + j*(127) --165 + j*(-45) -199 + j*(-132) -242 + j*(-7) --489 + j*(-55) --220 + j*(-413) -80 + j*(-27) --104 + j*(103) --245 + j*(383) --40 + j*(-466) -197 + j*(144) --98 + j*(13) --8 + j*(345) -335 + j*(190) -42 + j*(35) -157 + j*(58) -175 + j*(-229) -284 + j*(-218) -421 + j*(283) -272 + j*(-241) --252 + j*(157) --209 + j*(22) --40 + j*(-61) --30 + j*(84) -293 + j*(-244) --286 + j*(241) --197 + j*(-78) --107 + j*(-2) --329 + j*(-105) -93 + j*(-472) -187 + j*(-107) --279 + j*(150) --337 + j*(211) -117 + j*(-244) --221 + j*(267) -224 + j*(70) -174 + j*(168) --124 + j*(-14) -16 + j*(-190) --207 + j*(305) -143 + j*(54) --124 + j*(30) -43 + j*(-15) --67 + j*(-205) -21 + j*(-163) -157 + j*(-183) --59 + j*(-42) --53 + j*(-147) -231 + j*(30) --61 + j*(-77) -4 + j*(-422) --378 + j*(259) -74 + j*(-154) -36 + j*(153) --182 + j*(-66) -189 + j*(-37) --129 + j*(-29) -46 + j*(-117) --88 + j*(-76) --23 + j*(164) --111 + j*(-12) --228 + j*(-86) -134 + j*(-25) --142 + j*(93) --182 + j*(25) -215 + j*(-70) -181 + j*(-52) -212 + j*(156) -421 + j*(-248) -52 + j*(-489) -36 + j*(86) -105 + j*(-277) -283 + j*(-57) -250 + j*(73) -86 + j*(-120) --230 + j*(-105) --86 + j*(-75) --118 + j*(88) -59 + j*(-71) --106 + j*(-66) --314 + j*(-8) --16 + j*(270) --138 + j*(189) --151 + j*(-110) -365 + j*(-158) --216 + j*(-23) -4 + j*(181) --245 + j*(88) --132 + j*(202) --115 + j*(-160) -69 + j*(310) -47 + j*(45) -104 + j*(72) -260 + j*(204) --190 + j*(46) --192 + j*(312) -8 + j*(-155) --162 + j*(90) --115 + j*(44) --37 + j*(-298) --72 + j*(238) -170 + j*(310) -72 + j*(248) --28 + j*(151) -103 + j*(-130) -78 + j*(-173) -120 + j*(-121) -435 + j*(-305) --20 + j*(45) --93 + j*(235) -66 + j*(-35) -204 + j*(4) --134 + j*(50) --397 + j*(-16) -91 + j*(166) -112 + j*(-139) --42 + j*(-366) -25 + j*(223) -79 + j*(-212) --67 + j*(-242) --235 + j*(-83) --160 + j*(62) -124 + j*(347) -110 + j*(-49) -127 + j*(49) -167 + j*(-341) --427 + j*(-66) --172 + j*(82) --130 + j*(-25) --9 + j*(-11) -99 + j*(252) --225 + j*(-153) --220 + j*(175) -141 + j*(122) -110 + j*(288) --286 + j*(149) --47 + j*(218) -322 + j*(127) -159 + j*(101) --252 + j*(185) --443 + j*(-124) -10 + j*(165) -182 + j*(169) --32 + j*(-81) --44 + j*(-41) --229 + j*(50) -157 + j*(421) --155 + j*(-18) --85 + j*(-13) -148 + j*(-432) --298 + j*(-108) --260 + j*(219) -272 + j*(-179) -35 + j*(-123) -137 + j*(8) -29 + j*(-116) -84 + j*(167) -308 + j*(-47) -204 + j*(64) -339 + j*(-60) --224 + j*(-70) -186 + j*(730) --59 + j*(86) -66 + j*(-30) --16 + j*(-260) --309 + j*(200) --143 + j*(-127) -33 + j*(-50) -12 + j*(-74) --113 + j*(-52) --31 + j*(197) -330 + j*(197) -264 + j*(-106) -214 + j*(-164) --8 + j*(431) --143 + j*(66) -98 + j*(66) --65 + j*(92) -233 + j*(145) --93 + j*(133) -28 + j*(-104) --283 + j*(89) -91 + j*(-319) -53 + j*(111) -57 + j*(139) -90 + j*(88) -45 + j*(66) --43 + j*(140) -307 + j*(127) -173 + j*(-86) -115 + j*(-327) -255 + j*(-238) -212 + j*(-170) -173 + j*(279) -49 + j*(142) -6 + j*(3) -218 + j*(184) --39 + j*(-110) --10 + j*(-238) -30 + j*(303) -35 + j*(-55) -6 + j*(-54) -140 + j*(-167) -62 + j*(52) -204 + j*(-169) --64 + j*(163) --135 + j*(70) -82 + j*(63) -21 + j*(80) --81 + j*(-139) --84 + j*(76) --129 + j*(-13) --10 + j*(-159) -27 + j*(192) --158 + j*(118) -81 + j*(-167) -64 + j*(-67) --82 + j*(48) --18 + j*(102) --343 + j*(83) -161 + j*(-159) --10 + j*(460) --13 + j*(-252) -148 + j*(-252) --69 + j*(61) --152 + j*(48) -38 + j*(137) -90 + j*(40) -39 + j*(-65) -85 + j*(244) --76 + j*(-138) --209 + j*(59) --16 + j*(-194) -424 + j*(175) --57 + j*(-143) -21 + j*(239) -93 + j*(93) -75 + j*(151) --66 + j*(-127) -124 + j*(57) -78 + j*(142) --124 + j*(107) --184 + j*(-105) --43 + j*(83) -86 + j*(50) --46 + j*(1) -108 + j*(-211) -47 + j*(-100) --136 + j*(-327) -45 + j*(124) -471 + j*(-310) --72 + j*(52) --329 + j*(-104) -34 + j*(260) -433 + j*(-45) --202 + j*(-414) --115 + j*(-4) --67 + j*(143) --21 + j*(462) -74 + j*(-28) --301 + j*(-155) -107 + j*(-202) --85 + j*(26) --31 + j*(322) -416 + j*(352) --236 + j*(-16) -15 + j*(235) --250 + j*(120) --171 + j*(-234) -380 + j*(-51) -301 + j*(91) -118 + j*(79) -20 + j*(-35) -106 + j*(175) --217 + j*(-156) -146 + j*(156) --88 + j*(237) -573 + j*(-96) -68 + j*(90) -31 + j*(-156) --256 + j*(41) -119 + j*(249) -40 + j*(115) -82 + j*(131) -71 + j*(67) --373 + j*(37) -78 + j*(-76) --20 + j*(71) --38 + j*(-23) -117 + j*(-29) --78 + j*(-358) --199 + j*(-98) -228 + j*(165) -51 + j*(-88) --136 + j*(300) -76 + j*(46) --58 + j*(-200) -82 + j*(-96) --204 + j*(-250) -209 + j*(462) --178 + j*(20) --187 + j*(236) -296 + j*(-223) --211 + j*(-119) --232 + j*(199) --223 + j*(-18) -101 + j*(165) --349 + j*(-64) --121 + j*(-27) --192 + j*(513) -35 + j*(-97) -139 + j*(103) -209 + j*(-49) -97 + j*(73) -105 + j*(3) -54 + j*(-61) --60 + j*(257) -112 + j*(57) -193 + j*(-144) -88 + j*(24) -150 + j*(-133) -42 + j*(90) -409 + j*(-157) --37 + j*(-123) -156 + j*(136) --146 + j*(61) -153 + j*(-356) --45 + j*(-37) --69 + j*(198) --408 + j*(202) --18 + j*(102) -259 + j*(-2) -220 + j*(-238) --82 + j*(-42) -68 + j*(65) --25 + j*(144) -303 + j*(-100) -6 + j*(81) --25 + j*(47) -106 + j*(245) --204 + j*(-276) -59 + j*(23) --472 + j*(161) --196 + j*(-26) -266 + j*(-304) -132 + j*(-221) --108 + j*(28) --82 + j*(-34) --107 + j*(-3) --110 + j*(91) --11 + j*(-317) -106 + j*(76) -28 + j*(-119) -32 + j*(-52) --256 + j*(33) --46 + j*(-450) --10 + j*(-294) -454 + j*(-266) -89 + j*(-168) -100 + j*(-173) -240 + j*(71) -69 + j*(-199) --110 + j*(71) --36 + j*(18) --145 + j*(103) --317 + j*(-51) -11 + j*(62) -184 + j*(78) -182 + j*(-217) --168 + j*(-93) --58 + j*(75) --173 + j*(-167) --139 + j*(153) -47 + j*(-235) -128 + j*(-67) --226 + j*(143) --220 + j*(-101) -240 + j*(-123) --86 + j*(-377) -52 + j*(30) --39 + j*(-147) -236 + j*(-35) -150 + j*(-226) --52 + j*(-192) --37 + j*(187) --201 + j*(52) --146 + j*(116) --168 + j*(123) -54 + j*(-331) --33 + j*(-58) --139 + j*(-2) -23 + j*(-123) -94 + j*(-83) -127 + j*(158) --29 + j*(-93) -148 + j*(269) --21 + j*(227) --178 + j*(-3) --72 + j*(-140) -35 + j*(13) --14 + j*(122) --113 + j*(63) --177 + j*(6) --291 + j*(250) --184 + j*(260) --119 + j*(-229) --255 + j*(-19) --83 + j*(-202) -14 + j*(-102) --83 + j*(91) -100 + j*(-115) --289 + j*(83) --209 + j*(-58) --3 + j*(-247) -164 + j*(-134) -380 + j*(18) -40 + j*(-62) --132 + j*(-80) --1 + j*(-203) --175 + j*(-139) -50 + j*(92) --28 + j*(-29) -181 + j*(40) --241 + j*(40) -221 + j*(166) -81 + j*(-112) -4 + j*(-86) --7 + j*(-132) --78 + j*(-117) --152 + j*(92) --62 + j*(-200) --28 + j*(72) -186 + j*(-240) --9 + j*(148) -81 + j*(-139) --62 + j*(-86) --14 + j*(-98) -125 + j*(-161) --198 + j*(306) --57 + j*(33) -122 + j*(-140) --69 + j*(-103) --66 + j*(308) --9 + j*(206) --63 + j*(33) -175 + j*(15) --42 + j*(-182) -6 + j*(45) --218 + j*(15) --93 + j*(-39) -30 + j*(81) -66 + j*(405) --52 + j*(373) -467 + j*(55) -17 + j*(81) -145 + j*(226) --86 + j*(-193) --112 + j*(-109) -203 + j*(-74) --12 + j*(-225) -52 + j*(-145) --61 + j*(330) -98 + j*(-218) -114 + j*(-56) -31 + j*(-127) --337 + j*(-109) -212 + j*(-71) --111 + j*(-33) -113 + j*(250) -195 + j*(-205) --23 + j*(88) -151 + j*(-217) -105 + j*(-339) -139 + j*(275) --42 + j*(407) -215 + j*(-210) --390 + j*(-214) --330 + j*(-141) --125 + j*(-173) -164 + j*(-199) -262 + j*(43) -172 + j*(355) -69 + j*(151) --35 + j*(-54) --218 + j*(-117) -13 + j*(276) --42 + j*(-181) -176 + j*(-191) --174 + j*(-44) --300 + j*(-130) -29 + j*(-37) --274 + j*(-3) --23 + j*(57) -122 + j*(-143) -215 + j*(17) -78 + j*(110) --305 + j*(83) --4 + j*(43) -92 + j*(-425) --323 + j*(-36) --18 + j*(-63) -63 + j*(8) -50 + j*(170) -105 + j*(79) --18 + j*(-273) --66 + j*(-273) -86 + j*(-55) -173 + j*(-37) --87 + j*(30) -107 + j*(-247) -57 + j*(134) --118 + j*(518) -164 + j*(-260) -155 + j*(-93) -95 + j*(42) -293 + j*(-62) --26 + j*(250) -129 + j*(216) -86 + j*(69) -191 + j*(1) -214 + j*(-134) --308 + j*(-433) --33 + j*(-70) --98 + j*(57) -116 + j*(19) --248 + j*(185) -74 + j*(-148) --2 + j*(-165) -32 + j*(238) --4 + j*(170) --112 + j*(-122) -343 + j*(62) -145 + j*(72) --62 + j*(383) --105 + j*(-106) --480 + j*(200) -184 + j*(346) -83 + j*(-158) -187 + j*(170) --105 + j*(-212) --326 + j*(140) -240 + j*(-288) -107 + j*(-84) --231 + j*(-215) --162 + j*(99) --205 + j*(202) --89 + j*(170) -128 + j*(-134) -31 + j*(-245) --21 + j*(45) --5 + j*(32) --71 + j*(138) --300 + j*(55) -31 + j*(-25) --2 + j*(153) -163 + j*(-122) --132 + j*(-221) -192 + j*(62) --168 + j*(4) --10 + j*(-241) -193 + j*(-8) -31 + j*(-57) --58 + j*(-64) --134 + j*(-218) -78 + j*(-81) --13 + j*(107) --163 + j*(-23) --287 + j*(189) --226 + j*(-65) -54 + j*(-36) -25 + j*(260) -177 + j*(167) --83 + j*(245) --95 + j*(-302) -97 + j*(-70) -135 + j*(-128) -15 + j*(-54) -57 + j*(-5) -33 + j*(9) -196 + j*(297) --26 + j*(-111) --112 + j*(211) --215 + j*(54) --286 + j*(-7) -157 + j*(81) -626 + j*(96) -157 + j*(170) --2 + j*(116) --131 + j*(10) -443 + j*(48) --343 + j*(-14) --46 + j*(136) -235 + j*(98) -298 + j*(-99) -27 + j*(-122) --303 + j*(269) --65 + j*(-224) -86 + j*(119) -363 + j*(-146) -289 + j*(112) -416 + j*(-343) -23 + j*(62) -359 + j*(-118) -43 + j*(-156) -3 + j*(-25) --28 + j*(112) -100 + j*(211) --28 + j*(47) --169 + j*(18) -107 + j*(-104) --50 + j*(-117) -269 + j*(-52) -13 + j*(-81) --108 + j*(12) --103 + j*(-257) --258 + j*(93) --202 + j*(211) --117 + j*(-83) -5 + j*(-173) --289 + j*(281) --30 + j*(175) --20 + j*(-96) -177 + j*(40) --42 + j*(-80) --156 + j*(-88) --87 + j*(56) -112 + j*(42) --115 + j*(-334) -121 + j*(123) --197 + j*(308) -43 + j*(-219) --191 + j*(-131) -19 + j*(-239) --103 + j*(-7) --67 + j*(-83) --372 + j*(-101) -211 + j*(-40) --242 + j*(-88) --66 + j*(-199) --8 + j*(30) -183 + j*(-58) -59 + j*(220) -288 + j*(62) -233 + j*(109) -23 + j*(127) --99 + j*(-173) --48 + j*(-95) -182 + j*(167) -146 + j*(-223) -209 + j*(-64) -23 + j*(243) -65 + j*(78) --36 + j*(30) --384 + j*(-61) -187 + j*(9) --46 + j*(-52) -187 + j*(-119) -26 + j*(199) --296 + j*(-226) -224 + j*(-408) --184 + j*(221) --184 + j*(174) -83 + j*(107) --125 + j*(-95) -417 + j*(197) -10 + j*(-238) -32 + j*(-39) --59 + j*(161) -74 + j*(272) -291 + j*(139) --144 + j*(81) --321 + j*(0) -125 + j*(-56) --44 + j*(32) -57 + j*(-141) --115 + j*(32) -91 + j*(103) --204 + j*(-151) --112 + j*(-84) --49 + j*(42) -67 + j*(-351) --51 + j*(61) --269 + j*(54) --247 + j*(-315) -38 + j*(-28) -17 + j*(-354) -157 + j*(-127) -267 + j*(85) -137 + j*(-86) --77 + j*(-158) -344 + j*(-275) --101 + j*(136) --156 + j*(-459) --9 + j*(-119) -344 + j*(33) -16 + j*(-237) -74 + j*(-71) --19 + j*(321) -228 + j*(-115) --228 + j*(82) --291 + j*(49) --216 + j*(-457) --161 + j*(-90) --145 + j*(85) --417 + j*(130) --32 + j*(51) --341 + j*(-24) -60 + j*(174) --70 + j*(220) --177 + j*(-25) --42 + j*(-177) -141 + j*(-44) -126 + j*(-156) -180 + j*(-93) -239 + j*(-163) --242 + j*(-108) -74 + j*(133) -24 + j*(-28) --310 + j*(242) -134 + j*(201) --296 + j*(119) --98 + j*(-12) -69 + j*(71) --313 + j*(-73) -28 + j*(-25) -62 + j*(-102) --325 + j*(136) -322 + j*(-87) -64 + j*(247) --152 + j*(86) -95 + j*(-110) -145 + j*(344) -95 + j*(-163) --30 + j*(-364) -276 + j*(-101) -104 + j*(-206) -119 + j*(-93) --153 + j*(324) --3 + j*(-38) -70 + j*(83) --1 + j*(-329) --12 + j*(122) -41 + j*(104) --51 + j*(-198) -129 + j*(61) -4 + j*(23) -214 + j*(-16) --95 + j*(90) --84 + j*(-9) --159 + j*(78) --108 + j*(278) -156 + j*(-250) -106 + j*(172) -184 + j*(155) -159 + j*(47) --63 + j*(87) --8 + j*(115) --214 + j*(-180) --78 + j*(-164) -63 + j*(-165) --56 + j*(290) --69 + j*(-195) --155 + j*(53) -139 + j*(180) -205 + j*(-108) -30 + j*(342) --103 + j*(37) --204 + j*(-105) --125 + j*(-243) -211 + j*(306) --264 + j*(-107) --119 + j*(-308) -34 + j*(163) -5 + j*(112) -279 + j*(43) -209 + j*(-43) -15 + j*(157) -262 + j*(-8) -26 + j*(194) -170 + j*(-77) --65 + j*(-503) -18 + j*(-21) -228 + j*(-116) --71 + j*(54) -98 + j*(-200) -273 + j*(0) --126 + j*(-49) -118 + j*(-24) --1 + j*(21) --122 + j*(74) -247 + j*(-27) --94 + j*(252) -31 + j*(-20) -153 + j*(44) -38 + j*(-140) -62 + j*(200) --21 + j*(-37) -126 + j*(191) --3 + j*(-28) -261 + j*(284) --329 + j*(-189) -23 + j*(-105) -200 + j*(-269) -113 + j*(36) -61 + j*(151) --50 + j*(49) --150 + j*(-70) --115 + j*(-88) --46 + j*(-153) -100 + j*(92) --61 + j*(138) --35 + j*(-166) --185 + j*(189) -254 + j*(-180) -47 + j*(464) -24 + j*(273) --240 + j*(-223) --3 + j*(-196) --204 + j*(189) --33 + j*(-244) --112 + j*(-252) --103 + j*(-173) --12 + j*(-321) --150 + j*(-90) --26 + j*(238) -209 + j*(-52) -217 + j*(262) --211 + j*(69) -165 + j*(177) -13 + j*(-94) --110 + j*(-168) -167 + j*(-127) --100 + j*(64) -98 + j*(164) -138 + j*(-101) -97 + j*(-344) --255 + j*(33) --40 + j*(-127) -99 + j*(-166) --106 + j*(-271) -240 + j*(18) --58 + j*(-147) --145 + j*(50) --203 + j*(-132) -12 + j*(-170) --270 + j*(175) --47 + j*(-71) -279 + j*(-226) -181 + j*(202) -24 + j*(13) -65 + j*(148) --98 + j*(240) -36 + j*(206) -134 + j*(12) --144 + j*(-184) --402 + j*(83) --103 + j*(119) --62 + j*(-148) --113 + j*(202) --266 + j*(41) -185 + j*(-2) --196 + j*(-76) --123 + j*(-203) --195 + j*(-21) --23 + j*(232) --156 + j*(225) -219 + j*(152) -155 + j*(-184) --100 + j*(-13) --29 + j*(-129) -357 + j*(-53) -192 + j*(-126) --6 + j*(-172) -57 + j*(114) -183 + j*(-358) -47 + j*(-211) --42 + j*(131) --194 + j*(-122) --171 + j*(304) -31 + j*(95) --160 + j*(281) -37 + j*(-166) --142 + j*(37) -6 + j*(342) --55 + j*(-177) --20 + j*(-42) --351 + j*(87) -225 + j*(-8) -92 + j*(258) -71 + j*(83) -103 + j*(-59) -182 + j*(42) -78 + j*(-264) --153 + j*(-325) --160 + j*(25) -21 + j*(91) --123 + j*(-245) -81 + j*(-151) -277 + j*(63) --86 + j*(-250) --173 + j*(30) -86 + j*(-86) -11 + j*(95) -61 + j*(-32) --122 + j*(25) --52 + j*(-103) --93 + j*(445) -105 + j*(16) --68 + j*(-42) -129 + j*(-107) --199 + j*(-258) --273 + j*(108) -93 + j*(4) -176 + j*(-44) -98 + j*(-21) --145 + j*(-4) --192 + j*(22) --33 + j*(96) --176 + j*(-115) --29 + j*(47) --221 + j*(98) -139 + j*(249) -260 + j*(-54) --64 + j*(-2) -252 + j*(-52) -150 + j*(-151) -6 + j*(145) --78 + j*(136) -315 + j*(91) -30 + j*(91) --70 + j*(2) -105 + j*(-147) --159 + j*(380) -475 + j*(-3) -221 + j*(130) -224 + j*(-352) -23 + j*(180) -57 + j*(19) --322 + j*(94) --28 + j*(-117) -156 + j*(-285) -68 + j*(109) --77 + j*(-47) -87 + j*(-23) -392 + j*(44) --187 + j*(-203) --108 + j*(-540) --227 + j*(45) -2 + j*(-269) --64 + j*(204) --185 + j*(-205) --119 + j*(2) -404 + j*(-132) --144 + j*(20) -160 + j*(181) --283 + j*(86) -33 + j*(-139) --195 + j*(69) -117 + j*(-152) --308 + j*(-221) -337 + j*(127) --18 + j*(-202) -118 + j*(-132) -13 + j*(-235) --29 + j*(-47) -206 + j*(41) --243 + j*(306) -5 + j*(137) --48 + j*(42) --547 + j*(-230) --20 + j*(53) --49 + j*(0) -20 + j*(211) --115 + j*(359) -22 + j*(158) --108 + j*(-13) -169 + j*(-289) -92 + j*(69) --124 + j*(95) -113 + j*(-54) --382 + j*(-159) -274 + j*(214) --21 + j*(224) -29 + j*(59) -496 + j*(233) --115 + j*(-141) -246 + j*(-170) --75 + j*(-33) -251 + j*(-71) -7 + j*(144) -119 + j*(-99) -197 + j*(16) -52 + j*(-139) -17 + j*(-294) --66 + j*(177) --299 + j*(-142) -139 + j*(142) -34 + j*(126) -16 + j*(260) -90 + j*(44) --303 + j*(196) -67 + j*(-71) -74 + j*(179) -211 + j*(-202) -349 + j*(378) -444 + j*(3) -31 + j*(98) --217 + j*(-99) -35 + j*(98) --111 + j*(211) -253 + j*(69) -312 + j*(-1) -139 + j*(163) --30 + j*(5) --177 + j*(112) --195 + j*(211) --254 + j*(-32) --90 + j*(8) -170 + j*(-214) -254 + j*(257) --179 + j*(6) --69 + j*(202) -98 + j*(128) --197 + j*(-299) --250 + j*(-177) -156 + j*(-23) --64 + j*(-156) --35 + j*(-64) -32 + j*(101) --92 + j*(-60) -180 + j*(22) -21 + j*(134) -166 + j*(-83) -423 + j*(7) -12 + j*(219) -37 + j*(168) -1 + j*(118) -42 + j*(-40) --148 + j*(-71) --93 + j*(-12) --103 + j*(-221) -298 + j*(49) -56 + j*(91) -340 + j*(52) --117 + j*(132) -10 + j*(24) --24 + j*(151) --82 + j*(-61) -126 + j*(-199) --42 + j*(249) -102 + j*(74) -53 + j*(126) -245 + j*(161) --50 + j*(285) -106 + j*(136) -235 + j*(-6) -120 + j*(-202) -165 + j*(-13) --181 + j*(81) -318 + j*(-256) --25 + j*(137) -153 + j*(128) -123 + j*(-73) -61 + j*(51) --190 + j*(268) --363 + j*(214) -11 + j*(42) -75 + j*(-95) --62 + j*(-16) --15 + j*(-403) --33 + j*(-66) -95 + j*(64) --129 + j*(-220) --33 + j*(33) --38 + j*(-90) -103 + j*(-49) -252 + j*(227) -25 + j*(-282) -98 + j*(64) -151 + j*(-88) --182 + j*(117) --89 + j*(-91) --313 + j*(-100) --117 + j*(-107) -8 + j*(-174) --83 + j*(-45) --324 + j*(83) -47 + j*(70) -97 + j*(81) -223 + j*(375) -43 + j*(13) --156 + j*(103) --112 + j*(117) --36 + j*(65) --18 + j*(174) --209 + j*(-86) -173 + j*(-186) -130 + j*(-262) -1 + j*(74) --180 + j*(31) --285 + j*(295) --158 + j*(-69) --165 + j*(86) --221 + j*(-175) --166 + j*(47) --202 + j*(162) -263 + j*(47) -187 + j*(-681) -63 + j*(-173) -74 + j*(119) -23 + j*(-364) --226 + j*(-106) --11 + j*(293) -32 + j*(243) -63 + j*(-235) --28 + j*(42) --165 + j*(228) -375 + j*(98) --142 + j*(115) -131 + j*(85) -41 + j*(-390) -202 + j*(339) --311 + j*(91) -194 + j*(-33) -49 + j*(479) -59 + j*(-524) -310 + j*(266) -131 + j*(-93) -77 + j*(6) --170 + j*(180) -45 + j*(165) --6 + j*(151) -291 + j*(-45) --74 + j*(163) -70 + j*(148) -209 + j*(-54) --52 + j*(296) -426 + j*(-81) -6 + j*(100) -305 + j*(14) -37 + j*(95) -11 + j*(294) --152 + j*(-21) --30 + j*(-151) -47 + j*(-141) -391 + j*(12) --60 + j*(-167) -16 + j*(110) -161 + j*(6) -213 + j*(158) -35 + j*(-8) -231 + j*(-83) -119 + j*(190) --35 + j*(191) -35 + j*(339) --9 + j*(35) -249 + j*(-193) --153 + j*(162) -175 + j*(-298) --35 + j*(150) --11 + j*(-353) -231 + j*(-64) --139 + j*(-264) --25 + j*(203) -105 + j*(-223) -94 + j*(125) -150 + j*(-11) -170 + j*(71) -69 + j*(13) -128 + j*(126) --145 + j*(44) --33 + j*(166) --4 + j*(153) --42 + j*(0) --281 + j*(40) --43 + j*(230) --202 + j*(-315) -210 + j*(-83) -193 + j*(-252) -221 + j*(-6) --262 + j*(81) --247 + j*(58) -66 + j*(122) -73 + j*(-110) --47 + j*(-16) --62 + j*(54) -153 + j*(-28) --28 + j*(-310) -55 + j*(-151) -92 + j*(27) --258 + j*(-75) -206 + j*(-6) -66 + j*(60) --139 + j*(-156) -50 + j*(134) --24 + j*(103) -165 + j*(155) -30 + j*(206) -67 + j*(74) -5 + j*(-52) --168 + j*(-119) -69 + j*(59) -54 + j*(-223) --196 + j*(1) -217 + j*(-269) -88 + j*(282) --47 + j*(33) --124 + j*(-10) --184 + j*(-282) --325 + j*(94) -40 + j*(331) --44 + j*(-128) -56 + j*(163) --107 + j*(-361) -278 + j*(120) -62 + j*(84) -206 + j*(219) --192 + j*(-233) -170 + j*(-263) -71 + j*(-114) -260 + j*(293) --4 + j*(91) --110 + j*(-105) --269 + j*(-175) --282 + j*(210) -213 + j*(-96) -312 + j*(33) --138 + j*(-117) -18 + j*(-124) -75 + j*(-114) --409 + j*(21) --54 + j*(98) -78 + j*(-160) -42 + j*(-13) --27 + j*(-368) --54 + j*(191) -87 + j*(95) --26 + j*(110) -15 + j*(-362) -325 + j*(-46) --42 + j*(-44) -108 + j*(-125) --49 + j*(117) --66 + j*(71) --21 + j*(-75) --243 + j*(-115) --77 + j*(46) -162 + j*(222) -165 + j*(131) -72 + j*(-66) --47 + j*(21) -112 + j*(-103) -130 + j*(-159) -64 + j*(-24) -124 + j*(-74) --255 + j*(204) -144 + j*(221) -28 + j*(-227) --13 + j*(278) -328 + j*(190) -253 + j*(482) -187 + j*(-18) --191 + j*(-597) -204 + j*(-31) --57 + j*(144) --252 + j*(-190) -221 + j*(-197) -35 + j*(139) -43 + j*(-66) --35 + j*(-119) -288 + j*(-279) -195 + j*(100) -215 + j*(312) --47 + j*(-114) --228 + j*(-92) -49 + j*(216) --376 + j*(82) --26 + j*(-35) -280 + j*(58) --412 + j*(-246) --158 + j*(-41) --95 + j*(316) -124 + j*(-209) --127 + j*(105) -69 + j*(89) --215 + j*(272) -88 + j*(-143) -112 + j*(-29) -69 + j*(40) --50 + j*(-23) -163 + j*(7) -69 + j*(-132) -60 + j*(115) -25 + j*(-206) --172 + j*(176) --535 + j*(-53) -141 + j*(52) -179 + j*(69) -65 + j*(29) -12 + j*(-180) --205 + j*(64) -82 + j*(136) -62 + j*(-64) -194 + j*(264) --332 + j*(177) --65 + j*(373) -34 + j*(107) --112 + j*(208) -140 + j*(-209) -269 + j*(4) --247 + j*(-40) --70 + j*(68) --179 + j*(-117) -102 + j*(-54) -148 + j*(-216) -446 + j*(35) -281 + j*(-202) --71 + j*(-89) -180 + j*(161) --77 + j*(-236) --33 + j*(-301) --11 + j*(-132) -71 + j*(-301) --94 + j*(43) --209 + j*(-148) -204 + j*(-35) -137 + j*(-66) -8 + j*(54) --186 + j*(-173) --82 + j*(-146) --218 + j*(-95) -202 + j*(-250) -212 + j*(-194) --2 + j*(-124) --425 + j*(190) --10 + j*(-141) --445 + j*(27) --66 + j*(-164) -13 + j*(-260) --109 + j*(132) -79 + j*(165) -39 + j*(259) -173 + j*(110) -35 + j*(264) --13 + j*(197) --47 + j*(-209) --219 + j*(-66) -93 + j*(142) --129 + j*(-158) -49 + j*(213) -270 + j*(57) --144 + j*(-371) --7 + j*(40) -276 + j*(-67) --144 + j*(94) --177 + j*(-30) --61 + j*(-129) --596 + j*(331) --67 + j*(214) --144 + j*(59) --301 + j*(-268) --146 + j*(-204) --117 + j*(-105) -90 + j*(24) --30 + j*(35) --166 + j*(-23) -92 + j*(-79) -106 + j*(-62) -127 + j*(400) --154 + j*(68) -31 + j*(354) -144 + j*(-104) -56 + j*(170) --74 + j*(25) --240 + j*(204) --111 + j*(-112) --57 + j*(69) -17 + j*(-59) --76 + j*(86) --168 + j*(262) --66 + j*(97) --360 + j*(224) --159 + j*(42) --131 + j*(-4) --68 + j*(-267) -110 + j*(151) --110 + j*(-136) --171 + j*(-18) --81 + j*(-235) --236 + j*(173) -378 + j*(-101) --203 + j*(47) -61 + j*(47) -12 + j*(349) -291 + j*(73) --470 + j*(73) -339 + j*(48) --1 + j*(-18) --132 + j*(-96) -86 + j*(63) --191 + j*(-190) --142 + j*(-22) --134 + j*(-180) --326 + j*(52) --198 + j*(-278) --88 + j*(146) --207 + j*(33) --192 + j*(-90) --55 + j*(-57) --156 + j*(64) --332 + j*(327) -235 + j*(-50) -65 + j*(373) -107 + j*(-127) -122 + j*(98) -123 + j*(-29) --61 + j*(-6) --35 + j*(58) -96 + j*(-22) -35 + j*(63) -123 + j*(-92) -172 + j*(-159) -240 + j*(57) --175 + j*(92) --87 + j*(-8) -122 + j*(-253) --236 + j*(-38) --163 + j*(300) --310 + j*(40) -87 + j*(-207) -454 + j*(68) --103 + j*(-186) -250 + j*(115) -474 + j*(156) -51 + j*(22) -31 + j*(2) -75 + j*(-193) --36 + j*(168) -162 + j*(-11) -86 + j*(187) --86 + j*(-121) -77 + j*(-82) -222 + j*(-158) --19 + j*(-135) -188 + j*(279) --4 + j*(198) -54 + j*(30) --199 + j*(173) -37 + j*(206) --16 + j*(359) -24 + j*(-164) -211 + j*(-117) -56 + j*(99) --17 + j*(32) -100 + j*(-287) --289 + j*(9) -122 + j*(158) -318 + j*(13) -59 + j*(-168) -78 + j*(218) --42 + j*(191) --202 + j*(-32) -74 + j*(99) --167 + j*(98) -64 + j*(343) -119 + j*(-105) --218 + j*(131) --116 + j*(-496) -44 + j*(267) --109 + j*(222) -42 + j*(40) --15 + j*(164) --74 + j*(308) --1 + j*(-144) --284 + j*(186) -146 + j*(-49) --244 + j*(240) --19 + j*(-161) -43 + j*(320) --136 + j*(20) -247 + j*(0) -69 + j*(-146) --141 + j*(400) --21 + j*(-227) -139 + j*(-40) -275 + j*(-26) --157 + j*(34) -28 + j*(83) --578 + j*(-7) --135 + j*(73) -76 + j*(148) --310 + j*(-154) -210 + j*(123) -52 + j*(-453) --257 + j*(14) -23 + j*(20) -130 + j*(202) -45 + j*(223) -299 + j*(-381) --103 + j*(-58) -39 + j*(40) --42 + j*(86) -161 + j*(-38) -129 + j*(-187) --84 + j*(-164) -8 + j*(-97) -110 + j*(172) -247 + j*(356) --310 + j*(-209) -46 + j*(13) -291 + j*(-132) -44 + j*(228) --43 + j*(166) --258 + j*(121) --17 + j*(-28) -327 + j*(-172) -336 + j*(153) -321 + j*(-74) -83 + j*(-168) -3 + j*(-115) -28 + j*(276) -124 + j*(-30) -88 + j*(-173) -341 + j*(-122) --32 + j*(288) -143 + j*(150) --389 + j*(-63) --136 + j*(4) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -]; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 78acc373ee..0f11447bf4 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -380,7 +380,7 @@ struct openair0_device_t { @param buff Buffer which holds the samples (2 dimensional) @param nsamps number of samples to be sent @param number of antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); @@ -390,7 +390,7 @@ struct openair0_device_t { @param buff Buffer which holds the samples (1 dimensional) @param nsamps number of samples to be sent @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 + @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); diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp index 1273097f3b..47bbadfe28 100644 --- a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp +++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp @@ -134,7 +134,7 @@ static void trx_iris_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @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 + @param flags flags must be set to true if timestamp parameter needs to be applied */ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 8976284345..7c0180e5e7 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -331,7 +331,7 @@ static void trx_usrp_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, @@ -352,7 +352,7 @@ static int trx_usrp_write(openair0_device *device, AssertFatal( MAX_WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", MAX_WRITE_THREAD_BUFFER_SIZE); - boolean_t first_packet_state=false,last_packet_state=false; + bool first_packet_state=false,last_packet_state=false; if (flags_lsb == 2) { // start of burst // s->tx_md.start_of_burst = true; @@ -481,7 +481,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ void *trx_usrp_write_thread(void * arg){ int ret=0; @@ -675,7 +675,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp } if (samples_received == nsamps) s->wait_for_first_pps=0; - // bring RX data into 12 LSBs for softmodem RX + // bring RX data into 12 LSBs for softmodem RX for (int i=0; itype=USRP_N300_DEV; - usrp_master_clock = 122.88e6; + if (product == "n320") + usrp_master_clock = 245.76e6; // N320 does not support 122.88e6 master clock rate + else + usrp_master_clock = 122.88e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); if ( 0 != system("sysctl -w net.core.rmem_max=62500000 net.core.wmem_max=62500000") ) diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index b62c1935d3..f6578d6e9a 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -158,7 +158,7 @@ static void trx_iqplayer_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { struct timespec req; diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index cf025680cd..17ab3cb734 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -187,7 +187,7 @@ int main(int argc, char *argv[]) { } uint64_t typeStamp=ENB_MAGICDL; - boolean_t raw=false; + bool raw = false; if ( argc == 5 ) { raw=true; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index d14267dcd8..c8e109d302 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -22,7 +22,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf index 52e4eec30e..a4c877a7ba 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index ab435c9686..e5478983cf 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index a04e0e6123..efa0d3e2fa 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index 426f9e782b..8a2ce9f63e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf index 216728577a..616f86a1cd 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf index 59d466656c..0818fe11d7 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf index 6af1356088..022f17e490 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf @@ -21,9 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index 2ae4df07d9..5c636af06c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index 21267870bd..812ac8dafb 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf index a0fd0bda9f..781384a789 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf index 5c8f90d9b5..1450c45eee 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index 7bf3626870..562e2b16ab 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 909c54b858..a8ecb8c4b6 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index d0f394be16..10122b9eb2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 0438e61337..20d01c2a00 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index 66c2151eb8..44f3889eec 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf index c6ea066fc4..fbafef81b4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf index fcfe58a3c0..38d6ed3c61 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf index 2ad9757cb1..b7da7b17f4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 44074f3fd9..9f78716bcc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf index 7ce150506f..1dcef89736 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 306e652eaa..9a3fe358a5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf index d08c0f14a0..9e1ae24d67 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf index e3204db8fa..9ec28b93e7 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf index 030dc10226..35778ef705 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf index 6aacd98c7f..a64a4c6022 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf @@ -44,7 +44,6 @@ gNBs = local_s_portd = 2152; remote_s_portc = 500; remote_s_portd = 2152; - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf index f95bdf91ae..4309c13dd3 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf index f91683897f..cb90889b52 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index cd84e699c7..42aa555771 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -28,9 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - min_rxtxtime = 2; - do_CSIRS = 1; do_SRS = 1; pdcch_ConfigSIB1 = ( @@ -342,4 +339,7 @@ log_config : ngap_log_level ="debug"; f1ap_log_level ="debug"; }; +<<<<<<< HEAD +======= +>>>>>>> origin/develop diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf index ff64fe718a..6abf2c19cc 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; min_rxtxtime = 6; 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 ef34e68934..30be597255 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 @@ -28,7 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_N1 = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; @@ -266,6 +265,7 @@ 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.4layer.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf index 74f2f9c11c..8ff83b5d02 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf @@ -32,10 +32,9 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 4; + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; pusch_AntennaPorts = 4; - sib1_tda = 0; pdcch_ConfigSIB1 = ( { @@ -73,15 +72,6 @@ gNBs = #pdcch-ConfigCommon initialDLBWPcontrolResourceSetZero = 12; initialDLBWPsearchSpaceZero = 0; - #pdsch-ConfigCommon - #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; #for DL slot - initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB - initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 - - initialDLBWPk0_1 = 0; #for mixed slot - initialDLBWPmappingType_1 = 0; - initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -136,19 +126,6 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, - # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; # used for UL slot - initialULBWPmappingType_0 = 1 - initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 - - initialULBWPk2_1 = 6; # used for mixed slot - initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 - - initialULBWPk2_2 = 7; # used for Msg.3 during RA - initialULBWPmappingType_2 = 1; - initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; 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 eceb7c1755..9d00ae20aa 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 @@ -28,7 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 2; do_CSIRS = 1; do_SRS = 1; @@ -264,6 +263,7 @@ 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.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf index 8ca0c08876..6719a5534d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf @@ -30,7 +30,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdcch_ConfigSIB1 = ( { 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 e3ecf87ca0..5f8bf45232 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 @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf index 763396998d..1f1f64ce3f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; @@ -318,4 +317,4 @@ log_config : rrc_log_level ="info"; ngap_log_level ="debug"; f1ap_log_level ="debug"; -}; \ No newline at end of file +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index bd3076a014..ad1471339a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; sib1_tda = 15; min_rxtxtime = 6; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf index 3d93f2cfab..24090bef85 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; @@ -318,4 +317,4 @@ log_config : rrc_log_level ="info"; ngap_log_level ="debug"; f1ap_log_level ="debug"; -}; \ No newline at end of file +}; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a3048995a5..3d62d5c19a 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -231,9 +231,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB, dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; // L2-emulator can work only one eNB. // memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - // memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + // memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); AssertFatal((ret= pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd, return %d\n",ret); ru->proc.instance_pre_scd++; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 836709b473..1d464cb90c 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -89,7 +89,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,int br_flag); void stop_RU(RU_t **rup,int nb_ru); -void do_ru_synch(RU_t *ru); +static void do_ru_synch(RU_t *ru); void configure_ru(int idx, void *arg); @@ -1059,7 +1059,7 @@ int wakeup_synch(RU_t *ru) { } -void do_ru_synch(RU_t *ru) { +static void do_ru_synch(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = ru->frame_parms; RU_proc_t *proc = &ru->proc; int rxs, ic, ret, i; @@ -1834,7 +1834,7 @@ static void *ru_thread( void *param ) { new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd\n"); ru->proc.instance_pre_scd++; @@ -1924,7 +1924,7 @@ static void *ru_thread( void *param ) { // This thread run the initial synchronization like a UE -void *ru_thread_synch(void *arg) { +static void *ru_thread_synch(void *arg) { RU_t *ru = (RU_t *)arg; __attribute__((unused)) LTE_DL_FRAME_PARMS *fp = ru->frame_parms; diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 1c887dd3c8..38b71238b8 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -29,6 +29,7 @@ #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" @@ -213,5 +214,19 @@ extern void init_UE_standalone_thread(int ue_idx); extern PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); extern void init_bler_table(void); - +void feptx_ofdm_2thread(RU_t *ru, + int frame, + int subframe); +void* ru_thread_control( void* param ); +void wait_eNBs(void); +void kill_feptx_thread(RU_t *ru); +void init_fep_thread(RU_t *ru, pthread_attr_t *attr_fep); +void init_feptx_thread(RU_t *ru, pthread_attr_t *attr_feptx); +void fep_full(RU_t *ru, int subframe); +void configure_ru(int, void *arg); +void configure_rru(int, void *arg); +void ru_fep_full_2thread(RU_t *ru,int subframe); +void feptx_ofdm(RU_t*ru, int frame_tx, int tti_tx); +void feptx_prec(struct RU_t_s *ru, int frame_tx, int tti_tx); +void fill_rf_config(RU_t *ru, char *rf_config_file); #endif diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 678b6e0401..05602b63da 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -176,7 +176,6 @@ extern char uecap_xer[1024]; char uecap_xer_in=0; int oaisim_flag=0; -//threads_t threads= {-1,-1,-1,-1,-1,-1,-1,-1}; /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution diff --git a/targets/TEST/PDCP/test_pdcp.c b/targets/TEST/PDCP/test_pdcp.c index b62edf1215..d6becf87c1 100644 --- a/targets/TEST/PDCP/test_pdcp.c +++ b/targets/TEST/PDCP/test_pdcp.c @@ -100,7 +100,7 @@ int main(int argc, char **argv) list_init(&test_pdu_rx_list, NULL); logInit(); - if (init_pdcp_entity(&pdcp_array[0]) == TRUE && init_pdcp_entity(&pdcp_array[1]) == TRUE) + if (init_pdcp_entity(&pdcp_array[0]) == true && init_pdcp_entity(&pdcp_array[1]) == true) msg("[TEST] PDCP entity initialization OK\n"); else { msg("[TEST] Cannot initialize PDCP entities!\n"); @@ -109,7 +109,7 @@ int main(int argc, char **argv) /* Initialize PDCP state variables */ for (index = 0; index < 2; ++index) { - if (pdcp_init_seq_numbers(&pdcp_array[index]) == FALSE) { + if (pdcp_init_seq_numbers(&pdcp_array[index]) == false) { msg("[TEST] Cannot initialize sequence numbers of PDCP entity %d!\n", index); exit(1); } else { @@ -120,11 +120,11 @@ int main(int argc, char **argv) #if TEST_RX_AND_TX_WINDOW /* Test TX window */ - if (test_tx_window() == FALSE) + if (test_tx_window() == false) test_result = 1; /* Test RX window */ - if (test_rx_window() == FALSE) + if (test_rx_window() == false) test_result = 1; #endif @@ -132,11 +132,11 @@ int main(int argc, char **argv) #if TEST_PDCP_DATA_REQUEST_AND_INDICATION /* Test pdcp_data_req() method in pdcp.c */ - if (test_pdcp_data_req() == FALSE) + if (test_pdcp_data_req() == false) test_result = 1; /* Test pdcp_data_ind() method in pdcp.c */ - if (test_pdcp_data_ind() == FALSE) + if (test_pdcp_data_ind() == false) test_result = 1; #endif @@ -150,10 +150,10 @@ int main(int argc, char **argv) return test_result; } -BOOL init_pdcp_entity(pdcp_t *pdcp_entity) +bool init_pdcp_entity(pdcp_t *pdcp_entity) { if (pdcp_entity == NULL) - return FALSE; + return false; /* * Initialize sequence number state variables of relevant PDCP entity @@ -171,10 +171,10 @@ BOOL init_pdcp_entity(pdcp_t *pdcp_entity) pdcp_entity->next_pdcp_rx_sn, pdcp_entity->tx_hfn, pdcp_entity->rx_hfn, \ pdcp_entity->last_submitted_pdcp_rx_sn, pdcp_entity->seq_num_size); - return TRUE; + return true; } -BOOL test_tx_window(void) +bool test_tx_window(void) { unsigned long index = 0; @@ -185,33 +185,33 @@ BOOL test_tx_window(void) msg("TX packet # %07lu seq # %04d hfn # %04d\n", index, pseudo_tx_sn, pdcp_array[0].tx_hfn); else { msg("TX packet is out-of-window!\n"); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_rx_window(void) +bool test_rx_window(void) { unsigned long index = 0; for (index = 0; index < NUMBER_OF_TEST_PACKETS; ++index) { u16 pseudo_rx_sn = (index == 0) ? 0 : index % WINDOW_SIZE; - if (pdcp_is_rx_seq_number_valid(pseudo_rx_sn, &pdcp_array[1]) == TRUE) { + if (pdcp_is_rx_seq_number_valid(pseudo_rx_sn, &pdcp_array[1]) == true) { msg("RX packet # %07lu seq # %04d last-submitted # %04d hfn # %04d\n", \ index, pdcp_array[1].next_pdcp_rx_sn, pdcp_array[1].last_submitted_pdcp_rx_sn, pdcp_array[1].rx_hfn); } else { msg("RX packet seq # %04lu is not valid!\n", index); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_pdcp_data_req(void) +bool test_pdcp_data_req(void) { unsigned char* pdcp_test_pdu_buffer = NULL; unsigned char pdcp_test_pdu_buffer_size = DUMMY_BUFFER_SIZE + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; @@ -224,7 +224,7 @@ BOOL test_pdcp_data_req(void) if (pdcp_test_pdu_buffer == NULL) { msg("Cannot allocate a buffer for test!\n"); - return FALSE; + return false; } /* @@ -241,7 +241,7 @@ BOOL test_pdcp_data_req(void) /* * Ask PDCP to create a PDU with given buffer and enqueue it to `test_pdu_tx_list` */ - if (pdcp_data_req(0, 0, 10, DUMMY_BUFFER, &pdcp_array[0], &test_pdu_tx_list) == TRUE) { + if (pdcp_data_req(0, 0, 10, DUMMY_BUFFER, &pdcp_array[0], &test_pdu_tx_list) == true) { msg("[TEST] Starting to dissect PDU created by PDCP...\n"); /* @@ -251,7 +251,7 @@ BOOL test_pdcp_data_req(void) if (pdcp_test_pdu_buffer_size == 0 ) { msg("[TEST] PDU created by pdcp_data_req() is invalid!\n"); - return FALSE; + return false; } /* @@ -269,7 +269,7 @@ BOOL test_pdcp_data_req(void) */ if (pdcp_test_pdu_buffer[0] & 0x80) { msg("[TEST] First bit is not 0, which means this is not a Data PDU!\n"); - return FALSE; + return false; } else { msg("[TEST] First bit is 0 so this is a Data PDU, OK\n"); } @@ -279,7 +279,7 @@ BOOL test_pdcp_data_req(void) */ if ((pdcp_test_pdu_buffer[0] & 0x70) != 0) { msg("[TEST] Reserved bits are not 0!\n"); - return FALSE; + return false; } else { msg("[TEST] Reserved bits are all 0, OK\n"); } @@ -292,21 +292,21 @@ BOOL test_pdcp_data_req(void) if (sequence_number != index % WINDOW_SIZE) { msg("[TEST] Sequence numbers are out-of-order!\n"); - return FALSE; + return false; } else { msg("[TEST] Sequence number is correct\n"); } } else { msg("[TEST] pdcp_data_req() returned FALSE!\n"); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_pdcp_data_ind(void) +bool test_pdcp_data_ind(void) { /* * This is the list that pdcp_data_ind() takes to put pdcp_data_ind_header_t @@ -341,9 +341,9 @@ BOOL test_pdcp_data_ind(void) test_sdu = list_remove_head(&test_pdu_rx_list); - if (pdcp_data_ind(0, 0, test_sdu_size, test_sdu, &pdcp_array[0], &test_pdu_indication_list) == FALSE) { + if (pdcp_data_ind(0, 0, test_sdu_size, test_sdu, &pdcp_array[0], &test_pdu_indication_list) == false) { msg("[TEST] pdcp_data_ind() failed to handle data indication!\n"); - return FALSE; + return false; } else { msg("[TEST] pdcp_data_ind() succcessfuly handled data indication\n"); } @@ -359,7 +359,7 @@ BOOL test_pdcp_data_ind(void) if (test_data_ind_header == NULL) { msg("[TEST] Data indication header is not valid!\n"); - return FALSE; + return false; } else { pdcp_data_ind_header_t* indication_header = (pdcp_data_ind_header_t*)test_data_ind_header->data; @@ -370,7 +370,7 @@ BOOL test_pdcp_data_ind(void) msg("[TEST] Radio bearer ID is correct\n"); } else { msg("[TEST] Radio bearer ID is not correct! (expected: 0, parsed: %d)\n", indication_header->rb_id); - return FALSE; + return false; } /* @@ -380,7 +380,7 @@ BOOL test_pdcp_data_ind(void) msg("[TEST] SDU size is correct\n"); } else { msg("[TEST] SDU size is not correct! (expected: %d, parsed: %d)\n", DUMMY_BUFFER_SIZE, indication_header->data_size); - return FALSE; + return false; } /* @@ -412,11 +412,11 @@ BOOL test_pdcp_data_ind(void) print_byte_stream("[TEST] TXed data: ", DUMMY_BUFFER, DUMMY_BUFFER_SIZE); print_byte_stream("[TEST] RXed data: ", (unsigned char*)&(test_data_ind_header->data[data_index]), DUMMY_BUFFER_SIZE); - return FALSE; + return false; } } - return TRUE; + return true; } diff --git a/targets/TEST/PDCP/test_pdcp.h b/targets/TEST/PDCP/test_pdcp.h index 0da174cc8c..629f6f2539 100644 --- a/targets/TEST/PDCP/test_pdcp.h +++ b/targets/TEST/PDCP/test_pdcp.h @@ -42,17 +42,17 @@ int pdcp_fifo_flush_sdus (void) { return 0; } int pdcp_fifo_read_input_sdus_remaining_bytes (void) { return 0; } int pdcp_fifo_read_input_sdus (void) { return 0; } -BOOL init_pdcp_entity(pdcp_t *pdcp_entity); -BOOL test_tx_window(void); -BOOL test_rx_window(void); -BOOL test_pdcp_data_req(void); -BOOL test_pdcp_data_ind(void); +bool init_pdcp_entity(pdcp_t *pdcp_entity); +bool test_tx_window(void); +bool test_rx_window(void); +bool test_pdcp_data_req(void); +bool test_pdcp_data_ind(void); /* * PDCP methods that are going to be utilised throughout the test */ -extern BOOL pdcp_init_seq_numbers(pdcp_t* pdcp_entity); +extern bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity); extern u16 pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity); -extern BOOL pdcp_is_rx_seq_number_valid(u16 seq_num, pdcp_t* pdcp_entity); +extern bool pdcp_is_rx_seq_number_valid(u16 seq_num, pdcp_t* pdcp_entity); #endif diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c index 378ee95c3b..7b80171724 100644 --- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c +++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c @@ -109,7 +109,7 @@ int pdcp_fifo_flush_sdus () {} int pdcp_fifo_read_input_sdus_remaining_bytes () {} int pdcp_fifo_read_input_sdus () {} -BOOL init_pdcp_entity(pdcp_t *pdcp_entity); +bool init_pdcp_entity(pdcp_t *pdcp_entity); //----------------------------------------------------------------------------- void pdcp_rlc_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_data_req *data_requestP, int* drop_countP, int *tx_packetsP, int* dropped_tx_packetsP) //----------------------------------------------------------------------------- @@ -230,7 +230,7 @@ int main(int argc, char **argv) pdcp_module_init(); logInit(); - if (init_pdcp_entity(&pdcp_array[0][1]) == TRUE && init_pdcp_entity(&pdcp_array[1][1]) == TRUE) + if (init_pdcp_entity(&pdcp_array[0][1]) == true && init_pdcp_entity(&pdcp_array[1][1]) == true) msg("PDCP entity initialization OK\n"); else { msg("Cannot initialize PDCP entities!\n"); @@ -239,7 +239,7 @@ int main(int argc, char **argv) /* Initialize PDCP state variables */ for (index = 0; index < 2; ++index) { - if (pdcp_init_seq_numbers(&pdcp_array[index][1]) == FALSE) { + if (pdcp_init_seq_numbers(&pdcp_array[index][1]) == false) { msg("Cannot initialize %s PDCP entity!\n", ((index == 0) ? "first" : "second")); exit(1); } @@ -275,11 +275,11 @@ int main(int argc, char **argv) } //----------------------------------------------------------------------------- -BOOL init_pdcp_entity(pdcp_t *pdcp_entity) +bool init_pdcp_entity(pdcp_t *pdcp_entity) //----------------------------------------------------------------------------- { if (pdcp_entity == NULL) - return FALSE; + return false; /* * Initialize sequence number state variables of relevant PDCP entity @@ -292,6 +292,6 @@ BOOL init_pdcp_entity(pdcp_t *pdcp_entity) pdcp_entity->last_submitted_pdcp_rx_sn = 4095; pdcp_entity->seq_num_size = 12; - return TRUE; + return true; } diff --git a/txsig0.m b/txsig0.m deleted file mode 100644 index e795208a15..0000000000 --- a/txsig0.m +++ /dev/null @@ -1,61441 +0,0 @@ -txs0 = [-194 + j*(-202) --136 + j*(186) -248 + j*(59) -61 + j*(-331) --327 + j*(-134) --161 + j*(205) -70 + j*(64) --84 + j*(-35) --82 + j*(168) -170 + j*(116) -105 + j*(-159) --163 + j*(-94) --102 + j*(147) -100 + j*(89) -31 + j*(-79) --114 + j*(4) --25 + j*(144) -112 + j*(64) -41 + j*(-65) --84 + j*(9) --18 + j*(151) -137 + j*(129) -190 + j*(9) -163 + j*(-89) -85 + j*(-173) --68 + j*(-154) --93 + j*(26) -119 + j*(64) -183 + j*(-209) --139 + j*(-343) --365 + j*(-29) --107 + j*(252) -180 + j*(51) -11 + j*(-232) --279 + j*(-96) --200 + j*(193) -42 + j*(170) -37 + j*(-5) --93 + j*(13) --81 + j*(137) -21 + j*(187) -158 + j*(174) -303 + j*(-10) -155 + j*(-324) --275 + j*(-277) --348 + j*(180) -57 + j*(327) -197 + j*(1) --89 + j*(-71) --107 + j*(244) -254 + j*(283) -382 + j*(-61) -137 + j*(-263) --69 + j*(-141) --19 + j*(32) -138 + j*(8) -135 + j*(-159) --20 + j*(-175) --9 + j*(-51) -126 + j*(-153) --52 + j*(-384) --409 + j*(-234) --389 + j*(165) --78 + j*(276) -81 + j*(133) -94 + j*(11) -42 + j*(-99) --103 + j*(-112) --155 + j*(25) --57 + j*(74) --47 + j*(23) --64 + j*(69) -36 + j*(51) --16 + j*(-105) --230 + j*(-46) --211 + j*(189) --51 + j*(221) --39 + j*(208) -67 + j*(312) -308 + j*(188) -240 + j*(-112) --30 + j*(-91) --16 + j*(126) -153 + j*(117) -170 + j*(12) -156 + j*(-11) -173 + j*(-64) -130 + j*(-112) -123 + j*(-123) -100 + j*(-220) --86 + j*(-247) --170 + j*(-43) -21 + j*(40) -64 + j*(-161) --175 + j*(-176) --196 + j*(100) -91 + j*(138) -151 + j*(-144) --111 + j*(-234) --230 + j*(-19) --85 + j*(96) --11 + j*(9) --78 + j*(-10) --66 + j*(57) --17 + j*(30) --70 + j*(21) --45 + j*(133) -139 + j*(109) -154 + j*(-121) --70 + j*(-189) --165 + j*(-28) --98 + j*(46) --93 + j*(60) --33 + j*(136) -93 + j*(59) --5 + j*(-81) --144 + j*(55) -36 + j*(194) -176 + j*(-16) --49 + j*(-146) --166 + j*(75) -32 + j*(179) -109 + j*(33) -25 + j*(9) -74 + j*(42) -80 + j*(-77) --93 + j*(-79) --105 + j*(128) -111 + j*(162) -170 + j*(-36) --4 + j*(-98) --60 + j*(74) -142 + j*(148) -281 + j*(-80) -70 + j*(-296) --184 + j*(-135) --49 + j*(103) -166 + j*(-62) --46 + j*(-301) --354 + j*(-80) --202 + j*(281) -147 + j*(244) -206 + j*(-15) -78 + j*(-109) -20 + j*(-95) --17 + j*(-116) --112 + j*(-98) --159 + j*(30) --44 + j*(146) -110 + j*(66) -59 + j*(-88) --69 + j*(-35) -13 + j*(67) -104 + j*(-51) --37 + j*(-129) --83 + j*(6) -40 + j*(-13) --67 + j*(-129) --181 + j*(74) -120 + j*(185) -238 + j*(-213) --223 + j*(-363) --411 + j*(107) --2 + j*(288) -109 + j*(-43) --169 + j*(-46) --73 + j*(214) -182 + j*(56) --7 + j*(-186) --223 + j*(5) --57 + j*(177) -38 + j*(27) --137 + j*(19) --122 + j*(259) -152 + j*(303) -272 + j*(86) -172 + j*(-42) -145 + j*(-28) -195 + j*(-117) -64 + j*(-272) --177 + j*(-182) --171 + j*(71) -32 + j*(98) -31 + j*(-51) --99 + j*(11) -8 + j*(153) -159 + j*(35) -35 + j*(-93) --64 + j*(65) -149 + j*(186) -355 + j*(-29) -238 + j*(-317) --43 + j*(-356) --204 + j*(-183) --149 + j*(-11) --34 + j*(-13) --62 + j*(-84) --139 + j*(-6) --34 + j*(103) -103 + j*(-2) -18 + j*(-142) --96 + j*(-79) --27 + j*(-25) --26 + j*(-159) --263 + j*(-175) --385 + j*(125) --127 + j*(377) -177 + j*(252) -168 + j*(13) -60 + j*(5) -144 + j*(21) -160 + j*(-194) --136 + j*(-288) --318 + j*(5) --82 + j*(217) -93 + j*(27) --91 + j*(-98) --199 + j*(90) --41 + j*(188) -8 + j*(95) --67 + j*(132) -27 + j*(257) -204 + j*(201) -247 + j*(55) -214 + j*(-49) -131 + j*(-134) --10 + j*(-97) -16 + j*(65) -221 + j*(31) -221 + j*(-237) --64 + j*(-323) --230 + j*(-107) --126 + j*(61) --33 + j*(42) --40 + j*(42) -20 + j*(91) -120 + j*(29) -89 + j*(-100) --38 + j*(-103) --58 + j*(13) -58 + j*(46) -122 + j*(-83) -0 + j*(-199) --163 + j*(-120) --140 + j*(45) --11 + j*(53) --18 + j*(-31) --82 + j*(17) -11 + j*(74) -59 + j*(-59) --120 + j*(-101) --171 + j*(128) -76 + j*(203) -172 + j*(-20) -10 + j*(-92) -9 + j*(9) -75 + j*(-86) --111 + j*(-147) --175 + j*(105) -122 + j*(173) -203 + j*(-151) --111 + j*(-262) --245 + j*(-17) --110 + j*(93) --74 + j*(53) --79 + j*(90) --29 + j*(81) --96 + j*(72) --87 + j*(255) -197 + j*(303) -325 + j*(8) -103 + j*(-132) -39 + j*(30) -215 + j*(1) -166 + j*(-223) --55 + j*(-224) --98 + j*(-93) --86 + j*(-68) --130 + j*(-1) --34 + j*(97) -81 + j*(-18) --69 + j*(-147) --237 + j*(30) --83 + j*(245) -132 + j*(166) -120 + j*(25) -91 + j*(37) -170 + j*(-23) -83 + j*(-180) --124 + j*(-100) --45 + j*(129) -206 + j*(34) -113 + j*(-245) --176 + j*(-175) --128 + j*(87) -92 + j*(37) -29 + j*(-153) --144 + j*(-103) --128 + j*(23) --92 + j*(30) --112 + j*(88) --8 + j*(170) -122 + j*(83) -81 + j*(-45) --4 + j*(-42) --18 + j*(-16) --43 + j*(-1) --42 + j*(64) -40 + j*(78) -47 + j*(6) --19 + j*(44) -76 + j*(154) -281 + j*(49) -264 + j*(-238) --18 + j*(-369) --266 + j*(-198) --245 + j*(78) --7 + j*(177) -168 + j*(-5) -40 + j*(-248) --272 + j*(-207) --366 + j*(132) --85 + j*(356) -208 + j*(202) -177 + j*(-63) -3 + j*(-96) --23 + j*(-18) --3 + j*(-49) --109 + j*(-69) --184 + j*(77) --69 + j*(223) -105 + j*(208) -198 + j*(93) -202 + j*(-50) -97 + j*(-165) --67 + j*(-153) --146 + j*(-14) --83 + j*(126) -72 + j*(153) -183 + j*(23) -98 + j*(-141) --86 + j*(-95) --59 + j*(91) -134 + j*(71) -122 + j*(-134) --97 + j*(-146) --147 + j*(77) -66 + j*(191) -257 + j*(23) -194 + j*(-226) --39 + j*(-298) --208 + j*(-178) --243 + j*(-25) --216 + j*(119) --76 + j*(247) -144 + j*(186) -151 + j*(-23) -4 + j*(-19) -91 + j*(98) -249 + j*(-80) -41 + j*(-301) --199 + j*(-124) --54 + j*(63) -53 + j*(-95) --144 + j*(-161) --214 + j*(38) --77 + j*(104) --69 + j*(55) --69 + j*(140) -83 + j*(153) -127 + j*(-1) -25 + j*(-45) -27 + j*(0) -44 + j*(-57) --45 + j*(-78) --70 + j*(5) --9 + j*(15) --13 + j*(-43) --80 + j*(-61) --170 + j*(-14) --212 + j*(145) --59 + j*(313) -175 + j*(250) -221 + j*(59) -145 + j*(-12) -130 + j*(-25) -116 + j*(-76) -69 + j*(-121) --23 + j*(-160) --188 + j*(-76) --166 + j*(193) -141 + j*(249) -243 + j*(-24) -41 + j*(-97) -64 + j*(44) -183 + j*(-84) --27 + j*(-175) --50 + j*(114) -363 + j*(58) -303 + j*(-504) --333 + j*(-527) --450 + j*(41) --40 + j*(153) --25 + j*(-122) --240 + j*(-37) --124 + j*(148) --1 + j*(45) --100 + j*(14) --57 + j*(126) -62 + j*(41) --56 + j*(-71) --175 + j*(71) --45 + j*(213) -107 + j*(142) -114 + j*(21) -66 + j*(-37) --12 + j*(-71) --130 + j*(-15) --141 + j*(177) -85 + j*(297) -323 + j*(107) -219 + j*(-204) --95 + j*(-180) --118 + j*(100) -119 + j*(148) -185 + j*(-22) -117 + j*(-76) -129 + j*(-119) -34 + j*(-238) --174 + j*(-164) --153 + j*(57) -23 + j*(79) -60 + j*(-21) -45 + j*(-59) -23 + j*(-130) --110 + j*(-151) --168 + j*(-12) --75 + j*(34) --113 + j*(-22) --182 + j*(123) -25 + j*(248) -192 + j*(50) -38 + j*(-102) --52 + j*(12) -51 + j*(23) -1 + j*(-83) --116 + j*(-6) --47 + j*(104) -17 + j*(71) -16 + j*(99) -153 + j*(109) -215 + j*(-111) --33 + j*(-237) --202 + j*(0) -14 + j*(183) -216 + j*(-10) -61 + j*(-235) --169 + j*(-145) --139 + j*(46) --11 + j*(21) --91 + j*(-76) --228 + j*(60) --99 + j*(269) -136 + j*(210) -139 + j*(28) -42 + j*(33) -100 + j*(93) -185 + j*(6) -139 + j*(-114) -26 + j*(-142) --59 + j*(-71) --20 + j*(39) -111 + j*(11) -86 + j*(-144) --77 + j*(-129) --51 + j*(8) -54 + j*(-62) --78 + j*(-164) --202 + j*(-3) --66 + j*(136) -41 + j*(61) -23 + j*(25) -78 + j*(16) -68 + j*(-111) --93 + j*(-116) --100 + j*(38) -25 + j*(27) --13 + j*(-73) --98 + j*(-31) --88 + j*(21) --105 + j*(69) --13 + j*(190) -216 + j*(78) -108 + j*(-244) --277 + j*(-153) --214 + j*(264) -196 + j*(235) -199 + j*(-131) --99 + j*(-150) --117 + j*(66) -24 + j*(66) --5 + j*(-31) --98 + j*(15) --83 + j*(126) -14 + j*(186) -138 + j*(156) -200 + j*(43) -163 + j*(-57) -107 + j*(-97) -49 + j*(-122) --23 + j*(-93) --13 + j*(-21) -56 + j*(-54) --11 + j*(-151) --169 + j*(-84) --148 + j*(123) -69 + j*(170) -175 + j*(-24) -16 + j*(-158) --123 + j*(-22) -7 + j*(114) -156 + j*(-19) -43 + j*(-183) --119 + j*(-129) --136 + j*(-23) --138 + j*(41) --78 + j*(157) -117 + j*(136) -134 + j*(-84) --78 + j*(-120) --107 + j*(64) -33 + j*(69) --13 + j*(-21) --76 + j*(95) -91 + j*(178) -231 + j*(29) -181 + j*(-138) -58 + j*(-223) --117 + j*(-201) --183 + j*(-8) --10 + j*(71) -25 + j*(-103) --186 + j*(-88) --157 + j*(153) -59 + j*(127) -13 + j*(-8) --35 + j*(103) -158 + j*(102) -157 + j*(-132) --30 + j*(-143) --12 + j*(-71) --68 + j*(-188) --312 + j*(-68) --202 + j*(255) -106 + j*(181) -32 + j*(-31) --72 + j*(78) -74 + j*(97) -14 + j*(-49) --103 + j*(99) -141 + j*(182) -200 + j*(-136) --147 + j*(-175) --165 + j*(148) -81 + j*(121) --36 + j*(-28) --121 + j*(200) -169 + j*(290) -270 + j*(55) -179 + j*(21) -314 + j*(-1) -285 + j*(-309) --81 + j*(-343) --148 + j*(-45) -36 + j*(-34) --51 + j*(-122) --74 + j*(53) -172 + j*(23) -110 + j*(-277) --204 + j*(-220) --161 + j*(42) -7 + j*(-23) --116 + j*(-115) --186 + j*(62) -4 + j*(139) -91 + j*(-23) --27 + j*(-114) --117 + j*(-51) --107 + j*(23) --71 + j*(40) --76 + j*(35) --93 + j*(89) --12 + j*(156) -100 + j*(99) -95 + j*(0) -68 + j*(-22) -71 + j*(-80) --33 + j*(-146) --141 + j*(-59) --110 + j*(25) --114 + j*(23) --142 + j*(128) -8 + j*(211) -113 + j*(82) -28 + j*(33) -90 + j*(103) -182 + j*(-69) --69 + j*(-202) --224 + j*(82) -57 + j*(229) -154 + j*(-28) --82 + j*(-46) --26 + j*(180) -177 + j*(80) -50 + j*(-60) --1 + j*(112) -234 + j*(100) -214 + j*(-171) --30 + j*(-161) --8 + j*(3) -81 + j*(-49) -11 + j*(-83) -39 + j*(-25) -76 + j*(-131) --100 + j*(-167) --144 + j*(49) -84 + j*(95) -136 + j*(-136) --80 + j*(-215) --209 + j*(-57) --156 + j*(109) -3 + j*(178) -167 + j*(73) -132 + j*(-123) --33 + j*(-134) --35 + j*(-33) -21 + j*(-82) --76 + j*(-132) --132 + j*(-34) --72 + j*(-1) --93 + j*(-41) --139 + j*(23) --83 + j*(71) --75 + j*(44) --97 + j*(95) --10 + j*(140) -38 + j*(66) --10 + j*(60) -47 + j*(98) -87 + j*(-15) --70 + j*(-41) --76 + j*(173) -202 + j*(187) -267 + j*(-129) --20 + j*(-264) --206 + j*(-71) --133 + j*(107) --13 + j*(140) -75 + j*(89) -69 + j*(-3) --16 + j*(7) -30 + j*(97) -139 + j*(17) -36 + j*(-110) --91 + j*(18) -63 + j*(139) -184 + j*(-37) -4 + j*(-156) --102 + j*(13) -51 + j*(100) -123 + j*(-25) -40 + j*(-88) --7 + j*(-67) --64 + j*(-44) --83 + j*(100) -135 + j*(192) -322 + j*(-47) -141 + j*(-305) --98 + j*(-221) --71 + j*(-95) --74 + j*(-156) --224 + j*(-89) --173 + j*(126) -46 + j*(119) -59 + j*(-66) --92 + j*(-74) --102 + j*(55) -17 + j*(83) -78 + j*(-22) --5 + j*(-134) --163 + j*(-98) --198 + j*(73) --69 + j*(168) -25 + j*(117) -40 + j*(82) -81 + j*(57) -89 + j*(-18) -42 + j*(-52) -33 + j*(-74) --54 + j*(-149) --226 + j*(-48) --151 + j*(182) -61 + j*(127) --40 + j*(-22) --134 + j*(177) -169 + j*(257) -239 + j*(-114) --183 + j*(-148) --180 + j*(333) -346 + j*(337) -386 + j*(-156) -13 + j*(-190) -69 + j*(57) -272 + j*(-112) -67 + j*(-338) --147 + j*(-214) --138 + j*(-105) --197 + j*(-58) --168 + j*(129) -66 + j*(134) -58 + j*(-88) --147 + j*(-33) --42 + j*(170) -154 + j*(37) -13 + j*(-136) --124 + j*(11) -17 + j*(112) -87 + j*(-14) --11 + j*(-47) --3 + j*(23) -49 + j*(-22) --16 + j*(-62) --42 + j*(8) -30 + j*(13) -21 + j*(-71) --76 + j*(-71) --110 + j*(18) --71 + j*(82) --9 + j*(115) -81 + j*(99) -123 + j*(-4) -43 + j*(-77) --13 + j*(-18) -59 + j*(-4) -41 + j*(-132) --149 + j*(-117) --168 + j*(110) -54 + j*(157) -94 + j*(-24) --43 + j*(-18) -30 + j*(95) -135 + j*(-37) --33 + j*(-132) --107 + j*(57) -92 + j*(104) -111 + j*(-83) --29 + j*(-65) -56 + j*(11) -83 + j*(-171) --190 + j*(-189) --227 + j*(131) -93 + j*(187) -159 + j*(-101) --77 + j*(-175) --156 + j*(-15) --83 + j*(51) --49 + j*(43) --36 + j*(27) --81 + j*(19) --98 + j*(130) -69 + j*(174) -136 + j*(-19) --67 + j*(-74) --95 + j*(139) -124 + j*(143) -112 + j*(-52) --35 + j*(-11) -42 + j*(84) -90 + j*(-14) --3 + j*(-4) -95 + j*(69) -164 + j*(-132) --128 + j*(-231) --281 + j*(105) -27 + j*(307) -236 + j*(92) -127 + j*(-53) -91 + j*(-12) -117 + j*(-66) -21 + j*(-92) -17 + j*(26) -163 + j*(13) -181 + j*(-146) -79 + j*(-215) -19 + j*(-230) --83 + j*(-263) --221 + j*(-168) --188 + j*(5) --35 + j*(-1) --52 + j*(-155) --252 + j*(-163) --347 + j*(56) --194 + j*(232) --23 + j*(169) --54 + j*(60) --143 + j*(129) --72 + j*(266) -100 + j*(289) -249 + j*(188) -310 + j*(-8) -184 + j*(-207) --50 + j*(-197) --107 + j*(-20) -9 + j*(33) -37 + j*(-66) --71 + j*(-104) --163 + j*(-24) --169 + j*(118) --42 + j*(227) -118 + j*(168) -116 + j*(40) -59 + j*(55) -148 + j*(66) -160 + j*(-96) --42 + j*(-122) --75 + j*(100) -170 + j*(142) -241 + j*(-99) -49 + j*(-201) --41 + j*(-86) -25 + j*(-41) -37 + j*(-102) --24 + j*(-126) --75 + j*(-99) --100 + j*(-59) --117 + j*(-15) --122 + j*(64) --17 + j*(167) -188 + j*(89) -176 + j*(-187) --116 + j*(-242) --204 + j*(13) -1 + j*(68) --25 + j*(-117) --233 + j*(-18) --103 + j*(222) -136 + j*(86) --18 + j*(-122) --207 + j*(60) --23 + j*(254) -156 + j*(115) -74 + j*(1) -53 + j*(74) -169 + j*(38) -151 + j*(-116) -9 + j*(-153) --66 + j*(-77) --56 + j*(-2) -1 + j*(18) -27 + j*(-35) --42 + j*(-64) --83 + j*(21) -1 + j*(78) -62 + j*(10) -25 + j*(-33) -25 + j*(-25) -24 + j*(-86) --94 + j*(-115) --179 + j*(21) --87 + j*(153) -40 + j*(136) -84 + j*(81) -120 + j*(39) -149 + j*(-49) -94 + j*(-165) --58 + j*(-222) --250 + j*(-126) --292 + j*(157) --4 + j*(361) -327 + j*(146) -220 + j*(-244) --158 + j*(-236) --211 + j*(86) -41 + j*(154) -88 + j*(-45) --88 + j*(-61) --89 + j*(115) -85 + j*(123) -98 + j*(-33) --39 + j*(-42) --38 + j*(100) -124 + j*(104) -147 + j*(-66) --16 + j*(-96) --28 + j*(74) -194 + j*(75) -242 + j*(-210) --58 + j*(-366) --318 + j*(-151) --255 + j*(142) --24 + j*(223) -139 + j*(105) -119 + j*(-82) --71 + j*(-118) --136 + j*(92) -116 + j*(196) -286 + j*(-92) -3 + j*(-344) --312 + j*(-116) --159 + j*(211) -137 + j*(116) -62 + j*(-134) --164 + j*(-58) --81 + j*(167) -156 + j*(90) -97 + j*(-168) --182 + j*(-148) --221 + j*(134) -23 + j*(240) -168 + j*(72) -91 + j*(-66) --8 + j*(-58) --41 + j*(-9) --33 + j*(50) -40 + j*(79) -105 + j*(7) -54 + j*(-72) --13 + j*(-45) -8 + j*(-11) -19 + j*(-43) --23 + j*(-54) --45 + j*(-25) --45 + j*(-5) --40 + j*(20) --13 + j*(32) --4 + j*(18) -0 + j*(25) -30 + j*(4) --22 + j*(-54) --124 + j*(45) -15 + j*(223) -294 + j*(79) -206 + j*(-286) --193 + j*(-308) --334 + j*(42) --115 + j*(271) -130 + j*(213) -218 + j*(28) -136 + j*(-144) --40 + j*(-163) --117 + j*(-43) --76 + j*(32) --50 + j*(56) -8 + j*(89) -77 + j*(14) --23 + j*(-69) --119 + j*(71) -39 + j*(196) -177 + j*(67) -111 + j*(-15) -162 + j*(22) -255 + j*(-180) --35 + j*(-395) --370 + j*(-116) --168 + j*(276) -217 + j*(171) -198 + j*(-155) --37 + j*(-199) --114 + j*(-66) --65 + j*(12) -12 + j*(21) -74 + j*(-71) --16 + j*(-208) --224 + j*(-183) --316 + j*(28) --198 + j*(214) --19 + j*(222) -58 + j*(128) -44 + j*(74) -54 + j*(69) -66 + j*(15) --12 + j*(-14) --53 + j*(98) -100 + j*(182) -267 + j*(35) -209 + j*(-199) --7 + j*(-283) --209 + j*(-177) --248 + j*(46) --88 + j*(182) -49 + j*(96) --12 + j*(27) --16 + j*(144) -192 + j*(141) -260 + j*(-132) -6 + j*(-308) --255 + j*(-176) --310 + j*(85) --154 + j*(310) -153 + j*(320) -295 + j*(34) -78 + j*(-156) --93 + j*(13) -53 + j*(149) -153 + j*(42) -105 + j*(16) -206 + j*(45) -294 + j*(-177) -48 + j*(-372) --206 + j*(-206) --146 + j*(11) --28 + j*(11) --23 + j*(-14) -11 + j*(-11) -11 + j*(-80) --82 + j*(-71) --68 + j*(40) -57 + j*(23) -50 + j*(-105) --58 + j*(-122) --83 + j*(-64) --75 + j*(-74) --138 + j*(-86) --218 + j*(-9) --206 + j*(144) --28 + j*(240) -173 + j*(89) -70 + j*(-199) --288 + j*(-182) --414 + j*(196) --140 + j*(471) -180 + j*(421) -344 + j*(233) -393 + j*(-2) -255 + j*(-228) -6 + j*(-238) --80 + j*(-84) --32 + j*(-26) --45 + j*(-15) --14 + j*(54) -83 + j*(-1) --13 + j*(-116) --156 + j*(29) -28 + j*(211) -238 + j*(10) -42 + j*(-211) --158 + j*(-20) -36 + j*(136) -151 + j*(-74) --80 + j*(-159) --156 + j*(83) -73 + j*(162) -150 + j*(-23) -24 + j*(-78) -12 + j*(1) -81 + j*(-30) -38 + j*(-105) --42 + j*(-90) --61 + j*(-25) --17 + j*(21) -47 + j*(-12) -19 + j*(-93) --73 + j*(-64) --35 + j*(26) -56 + j*(-37) --26 + j*(-142) --135 + j*(-66) --85 + j*(6) --86 + j*(-47) --186 + j*(16) --110 + j*(165) -38 + j*(110) --9 + j*(1) --79 + j*(61) --27 + j*(107) --32 + j*(104) -21 + j*(213) -260 + j*(155) -242 + j*(-181) --134 + j*(-202) --160 + j*(181) -224 + j*(190) -216 + j*(-189) --139 + j*(-156) --69 + j*(175) -260 + j*(72) -172 + j*(-259) --123 + j*(-233) --154 + j*(-45) --105 + j*(-16) --145 + j*(29) --96 + j*(141) -24 + j*(151) -79 + j*(110) -144 + j*(78) -197 + j*(-41) -103 + j*(-162) --15 + j*(-137) --24 + j*(-78) --23 + j*(-83) --43 + j*(-78) --48 + j*(-87) --113 + j*(-107) --196 + j*(-16) --129 + j*(103) --30 + j*(62) --91 + j*(1) --163 + j*(100) --78 + j*(225) -67 + j*(235) -181 + j*(153) -216 + j*(4) -111 + j*(-110) --6 + j*(-66) -16 + j*(-4) -25 + j*(-49) --65 + j*(-36) --69 + j*(85) -42 + j*(132) -122 + j*(88) -175 + j*(18) -159 + j*(-100) -31 + j*(-126) -30 + j*(-3) -199 + j*(-62) -119 + j*(-332) --223 + j*(-313) --296 + j*(4) --91 + j*(117) --18 + j*(42) -1 + j*(54) -105 + j*(-19) -12 + j*(-202) --216 + j*(-123) --162 + j*(92) --13 + j*(24) --153 + j*(-72) --262 + j*(153) --11 + j*(321) -198 + j*(113) -51 + j*(-77) --103 + j*(44) -4 + j*(185) -151 + j*(115) -144 + j*(-12) -74 + j*(-54) -22 + j*(-39) -2 + j*(20) -88 + j*(78) -228 + j*(-34) -148 + j*(-286) --177 + j*(-305) --310 + j*(6) --71 + j*(195) -112 + j*(17) --47 + j*(-148) --235 + j*(1) --142 + j*(242) -117 + j*(265) -272 + j*(52) -167 + j*(-184) --72 + j*(-199) --171 + j*(-28) --112 + j*(79) --78 + j*(122) -5 + j*(219) -218 + j*(185) -282 + j*(-69) -71 + j*(-206) --76 + j*(-67) -15 + j*(54) -127 + j*(-10) -110 + j*(-136) --12 + j*(-192) --136 + j*(-111) --108 + j*(28) -11 + j*(23) --10 + j*(-81) --129 + j*(-52) --131 + j*(86) --10 + j*(163) -151 + j*(122) -234 + j*(-81) -56 + j*(-294) --225 + j*(-198) --224 + j*(59) --66 + j*(95) --71 + j*(54) --40 + j*(144) -126 + j*(98) -96 + j*(-96) --75 + j*(-85) --69 + j*(23) --50 + j*(-3) --115 + j*(64) -8 + j*(177) -144 + j*(28) --23 + j*(-90) --106 + j*(107) -122 + j*(170) -179 + j*(-56) -0 + j*(-101) -4 + j*(23) -95 + j*(-48) --16 + j*(-141) --111 + j*(-45) --58 + j*(23) --47 + j*(-2) --88 + j*(36) --48 + j*(116) -69 + j*(120) -136 + j*(-18) --23 + j*(-159) --256 + j*(24) --80 + j*(365) -330 + j*(245) -287 + j*(-135) -37 + j*(-103) -168 + j*(-3) -186 + j*(-301) --249 + j*(-327) --316 + j*(146) -108 + j*(220) -131 + j*(-115) --116 + j*(-52) -32 + j*(124) -145 + j*(-91) --105 + j*(-140) --87 + j*(123) -180 + j*(47) -63 + j*(-209) --160 + j*(-81) --38 + j*(88) -64 + j*(-7) -20 + j*(-28) -115 + j*(-38) -99 + j*(-277) --234 + j*(-341) --409 + j*(-42) --264 + j*(163) --161 + j*(181) --78 + j*(243) -97 + j*(187) -78 + j*(-12) --109 + j*(10) --78 + j*(188) -74 + j*(170) -57 + j*(90) -52 + j*(166) -225 + j*(163) -296 + j*(-59) -115 + j*(-217) --72 + j*(-135) --82 + j*(17) --6 + j*(81) -66 + j*(100) -185 + j*(84) -301 + j*(-90) -166 + j*(-356) --186 + j*(-339) --274 + j*(-1) -9 + j*(103) -66 + j*(-180) --290 + j*(-209) --366 + j*(228) -91 + j*(401) -346 + j*(-5) -26 + j*(-292) --251 + j*(-59) --98 + j*(175) -66 + j*(78) --12 + j*(8) --7 + j*(115) -160 + j*(83) -155 + j*(-130) --54 + j*(-180) --153 + j*(-28) --89 + j*(84) --6 + j*(110) -89 + j*(86) -142 + j*(-53) --13 + j*(-197) --251 + j*(-72) --217 + j*(242) -96 + j*(346) -317 + j*(132) -251 + j*(-104) -109 + j*(-132) -105 + j*(-97) -118 + j*(-192) --37 + j*(-279) --204 + j*(-156) --153 + j*(13) --40 + j*(-14) --92 + j*(-90) --186 + j*(-26) --175 + j*(81) --127 + j*(153) --21 + j*(222) -151 + j*(170) -187 + j*(-21) -50 + j*(-118) --42 + j*(-59) --39 + j*(-8) --21 + j*(18) -40 + j*(1) -13 + j*(-132) --224 + j*(-133) --315 + j*(181) --11 + j*(388) -260 + j*(185) -177 + j*(-47) -52 + j*(-30) -74 + j*(-1) -69 + j*(-54) -11 + j*(-70) --47 + j*(-48) --98 + j*(51) -21 + j*(202) -278 + j*(107) -259 + j*(-214) --47 + j*(-292) --184 + j*(-76) --87 + j*(51) --16 + j*(53) -48 + j*(52) -106 + j*(-47) -0 + j*(-146) --110 + j*(-61) --61 + j*(11) --78 + j*(-21) --138 + j*(102) -61 + j*(233) -269 + j*(23) -98 + j*(-221) --117 + j*(-100) --11 + j*(49) -83 + j*(-84) --86 + j*(-168) --194 + j*(12) --35 + j*(151) -134 + j*(22) -34 + j*(-185) --217 + j*(-127) --222 + j*(148) -38 + j*(204) -94 + j*(-13) --94 + j*(-19) --34 + j*(184) -206 + j*(78) -87 + j*(-186) --176 + j*(-74) --70 + j*(165) -139 + j*(65) -45 + j*(-117) --125 + j*(-42) --93 + j*(124) -66 + j*(168) -198 + j*(37) -115 + j*(-163) --119 + j*(-122) --93 + j*(118) -155 + j*(82) -110 + j*(-169) --119 + j*(-132) --86 + j*(26) --31 + j*(-42) --178 + j*(-10) --111 + j*(211) -130 + j*(144) -46 + j*(-66) --131 + j*(70) -38 + j*(249) -221 + j*(107) -157 + j*(-16) -155 + j*(-5) -179 + j*(-116) -18 + j*(-182) --58 + j*(-21) -92 + j*(47) -168 + j*(-78) -130 + j*(-164) -100 + j*(-258) --71 + j*(-373) --326 + j*(-263) --372 + j*(6) --234 + j*(173) --55 + j*(218) -138 + j*(98) -81 + j*(-190) --284 + j*(-191) --366 + j*(220) -19 + j*(387) -223 + j*(95) -37 + j*(-59) --33 + j*(66) -74 + j*(77) -67 + j*(-16) -18 + j*(-8) -35 + j*(-17) --20 + j*(-47) --59 + j*(38) -51 + j*(74) -84 + j*(-63) --71 + j*(-116) --163 + j*(29) --78 + j*(157) -45 + j*(167) -136 + j*(98) -145 + j*(-29) -32 + j*(-86) --31 + j*(0) -45 + j*(35) -37 + j*(-54) --79 + j*(-17) --37 + j*(136) -124 + j*(117) -135 + j*(4) -116 + j*(9) -202 + j*(-54) -114 + j*(-238) --129 + j*(-163) --43 + j*(97) -244 + j*(-28) -110 + j*(-376) --279 + j*(-310) --317 + j*(26) --120 + j*(119) --50 + j*(67) --16 + j*(54) --6 + j*(-23) --122 + j*(-19) --99 + j*(146) -88 + j*(121) -55 + j*(-42) --49 + j*(33) -95 + j*(83) -111 + j*(-130) --130 + j*(-122) --85 + j*(98) -86 + j*(-28) --152 + j*(-158) --274 + j*(185) -112 + j*(320) -233 + j*(-37) --53 + j*(-80) -35 + j*(146) -236 + j*(-71) --59 + j*(-267) --232 + j*(49) -74 + j*(153) -74 + j*(-140) --220 + j*(-44) --60 + j*(252) -216 + j*(71) -47 + j*(-149) --83 + j*(-3) -47 + j*(13) --41 + j*(-135) --235 + j*(13) --110 + j*(233) -67 + j*(183) -64 + j*(119) -117 + j*(146) -194 + j*(61) -143 + j*(-20) -128 + j*(15) -204 + j*(-31) -170 + j*(-153) -68 + j*(-177) -22 + j*(-149) --2 + j*(-132) -5 + j*(-116) --2 + j*(-176) --142 + j*(-200) --238 + j*(-6) --39 + j*(161) -194 + j*(-13) -81 + j*(-310) --246 + j*(-333) --436 + j*(-70) --335 + j*(222) --67 + j*(279) -45 + j*(95) --96 + j*(21) --137 + j*(187) -50 + j*(249) -135 + j*(106) -70 + j*(63) -136 + j*(97) -212 + j*(-73) -5 + j*(-238) --239 + j*(-66) --150 + j*(211) -103 + j*(215) -163 + j*(35) -57 + j*(-25) -30 + j*(62) -146 + j*(84) -233 + j*(-52) -152 + j*(-210) --9 + j*(-251) --136 + j*(-193) --221 + j*(-83) --220 + j*(81) --87 + j*(194) -66 + j*(155) -107 + j*(48) -74 + j*(-18) -21 + j*(-40) --28 + j*(-1) -13 + j*(69) -110 + j*(30) -85 + j*(-83) --18 + j*(-68) -13 + j*(9) -90 + j*(-57) -10 + j*(-161) --117 + j*(-118) --137 + j*(-20) --113 + j*(33) --80 + j*(78) --25 + j*(77) --42 + j*(56) --46 + j*(147) -124 + j*(187) -217 + j*(-13) -31 + j*(-104) -2 + j*(95) -279 + j*(64) -256 + j*(-303) --119 + j*(-344) --187 + j*(-61) --23 + j*(-69) --168 + j*(-178) --296 + j*(68) --33 + j*(220) -90 + j*(-9) --116 + j*(-49) --62 + j*(161) -171 + j*(33) -8 + j*(-227) --273 + j*(-74) --165 + j*(191) -39 + j*(132) -1 + j*(-1) --91 + j*(30) --94 + j*(113) --35 + j*(174) -59 + j*(161) -62 + j*(87) -10 + j*(141) -151 + j*(231) -321 + j*(64) -194 + j*(-141) -42 + j*(-47) -175 + j*(44) -270 + j*(-148) -98 + j*(-295) --53 + j*(-226) --73 + j*(-174) --142 + j*(-168) --224 + j*(-60) --188 + j*(91) --53 + j*(160) -82 + j*(100) -92 + j*(-41) --30 + j*(-74) --54 + j*(42) -82 + j*(57) -119 + j*(-100) --28 + j*(-187) --156 + j*(-103) --156 + j*(23) --69 + j*(81) --1 + j*(32) --45 + j*(-26) --103 + j*(35) --39 + j*(94) --1 + j*(37) --69 + j*(52) --14 + j*(148) -107 + j*(83) -38 + j*(-28) --47 + j*(65) -69 + j*(149) -162 + j*(56) -148 + j*(-6) -187 + j*(-57) -151 + j*(-212) --47 + j*(-245) --120 + j*(-114) --88 + j*(-104) --215 + j*(-94) --254 + j*(150) -25 + j*(280) -215 + j*(49) -75 + j*(-141) --57 + j*(-86) --49 + j*(-52) --116 + j*(-78) --218 + j*(32) --154 + j*(216) -44 + j*(256) -159 + j*(120) -93 + j*(11) -29 + j*(79) -168 + j*(136) -289 + j*(-55) -121 + j*(-248) --80 + j*(-144) --9 + j*(2) -95 + j*(-88) --16 + j*(-204) --158 + j*(-133) --169 + j*(-13) --126 + j*(45) --87 + j*(78) --39 + j*(97) -15 + j*(76) -16 + j*(18) --62 + j*(27) --51 + j*(170) -177 + j*(209) -314 + j*(-57) -86 + j*(-280) --158 + j*(-137) --91 + j*(60) -25 + j*(33) -6 + j*(-6) -29 + j*(25) -83 + j*(-34) -33 + j*(-112) --38 + j*(-119) --115 + j*(-112) --223 + j*(7) --120 + j*(232) -189 + j*(190) -219 + j*(-157) --121 + j*(-256) --274 + j*(45) --37 + j*(234) -153 + j*(59) -25 + j*(-115) --133 + j*(-16) --61 + j*(133) -59 + j*(97) -47 + j*(34) -62 + j*(63) -148 + j*(-17) -33 + j*(-173) --186 + j*(-53) --88 + j*(214) -206 + j*(169) -242 + j*(-101) -56 + j*(-220) --110 + j*(-164) --190 + j*(8) --42 + j*(207) -250 + j*(103) -214 + j*(-243) --114 + j*(-279) --187 + j*(-39) --49 + j*(-1) --78 + j*(-83) --148 + j*(-26) --132 + j*(13) --185 + j*(52) --146 + j*(223) -103 + j*(230) -155 + j*(-30) --83 + j*(-110) --197 + j*(76) --116 + j*(229) -21 + j*(315) -247 + j*(280) -337 + j*(28) -148 + j*(-100) -95 + j*(46) -279 + j*(8) -224 + j*(-229) -4 + j*(-213) -19 + j*(-83) -58 + j*(-142) --37 + j*(-124) -52 + j*(-28) -164 + j*(-220) --91 + j*(-414) --366 + j*(-209) --298 + j*(42) --187 + j*(81) --144 + j*(138) -12 + j*(137) -37 + j*(-57) --192 + j*(-78) --225 + j*(185) -33 + j*(250) -116 + j*(46) --38 + j*(-6) --51 + j*(135) -100 + j*(148) -154 + j*(6) -57 + j*(-79) --26 + j*(-34) --6 + j*(18) -17 + j*(-15) --52 + j*(-29) --91 + j*(77) -27 + j*(167) -163 + j*(81) -145 + j*(-67) -37 + j*(-111) --34 + j*(-67) --49 + j*(-6) --13 + j*(38) -33 + j*(25) -28 + j*(-11) -10 + j*(5) -55 + j*(19) -85 + j*(-62) --13 + j*(-122) --99 + j*(-35) --28 + j*(44) -11 + j*(-31) --107 + j*(-26) --80 + j*(164) -177 + j*(151) -196 + j*(-140) --95 + j*(-177) --123 + j*(104) -161 + j*(116) -181 + j*(-173) --81 + j*(-233) --182 + j*(-49) --103 + j*(49) --45 + j*(55) --7 + j*(40) --18 + j*(9) --38 + j*(62) -76 + j*(97) -147 + j*(-59) -1 + j*(-163) --95 + j*(-69) --64 + j*(-48) --163 + j*(-59) --209 + j*(148) -40 + j*(250) -170 + j*(28) -2 + j*(-81) --56 + j*(37) -15 + j*(49) --16 + j*(30) -20 + j*(98) -111 + j*(29) -21 + j*(-49) --20 + j*(66) -112 + j*(75) -100 + j*(-32) -85 + j*(42) -291 + j*(-49) -173 + j*(-420) --298 + j*(-370) --324 + j*(59) --48 + j*(74) --159 + j*(-41) --181 + j*(245) -249 + j*(251) -287 + j*(-256) --209 + j*(-344) --335 + j*(52) --99 + j*(153) --103 + j*(59) --148 + j*(183) -20 + j*(267) -143 + j*(168) -164 + j*(77) -154 + j*(-22) -39 + j*(-74) --16 + j*(31) -81 + j*(57) -69 + j*(-30) -8 + j*(27) -122 + j*(63) -148 + j*(-88) -8 + j*(-102) -31 + j*(-4) -88 + j*(-91) --49 + j*(-115) --43 + j*(47) -124 + j*(12) -73 + j*(-129) -17 + j*(-69) -127 + j*(-136) --30 + j*(-349) --322 + j*(-190) --207 + j*(65) --92 + j*(-72) --361 + j*(-65) --357 + j*(356) -94 + j*(453) -255 + j*(125) -100 + j*(25) -146 + j*(93) -240 + j*(-49) -127 + j*(-201) --4 + j*(-204) --99 + j*(-184) --204 + j*(-93) --183 + j*(53) --101 + j*(95) --60 + j*(116) -37 + j*(127) -93 + j*(2) --21 + j*(-56) --40 + j*(37) -48 + j*(-22) --98 + j*(-139) --279 + j*(56) --123 + j*(288) -81 + j*(230) -97 + j*(149) -161 + j*(140) -210 + j*(7) -93 + j*(-68) -64 + j*(6) -116 + j*(-44) --8 + j*(-90) --49 + j*(92) -177 + j*(143) -261 + j*(-70) -144 + j*(-159) -139 + j*(-167) -78 + j*(-310) --162 + j*(-307) --234 + j*(-112) --184 + j*(-62) --274 + j*(4) --209 + j*(250) -97 + j*(261) -163 + j*(23) -49 + j*(-13) -113 + j*(1) -88 + j*(-163) --120 + j*(-135) --76 + j*(54) -69 + j*(-40) --93 + j*(-144) --165 + j*(64) -66 + j*(83) -15 + j*(-163) --262 + j*(-41) --98 + j*(272) -240 + j*(97) -84 + j*(-248) --245 + j*(-141) --202 + j*(138) --9 + j*(141) --1 + j*(28) --83 + j*(39) --77 + j*(132) -23 + j*(163) -81 + j*(83) -12 + j*(46) -16 + j*(149) -179 + j*(144) -218 + j*(-46) -69 + j*(-117) -20 + j*(-46) -28 + j*(-66) --68 + j*(-49) --46 + j*(98) -112 + j*(77) -72 + j*(-54) --12 + j*(48) -187 + j*(113) -289 + j*(-169) --6 + j*(-335) --197 + j*(-103) --42 + j*(43) -20 + j*(-68) --81 + j*(-54) --11 + j*(52) -110 + j*(-62) --29 + j*(-222) --240 + j*(-105) --187 + j*(134) -35 + j*(152) -90 + j*(-28) --54 + j*(-78) --71 + j*(60) -93 + j*(36) -40 + j*(-177) --226 + j*(-124) --188 + j*(163) -86 + j*(129) -23 + j*(-124) --231 + j*(-31) --148 + j*(234) -86 + j*(197) -88 + j*(45) -25 + j*(46) -52 + j*(56) -45 + j*(24) -30 + j*(45) -59 + j*(49) -66 + j*(45) -127 + j*(57) -200 + j*(-73) -43 + j*(-219) --136 + j*(-70) -16 + j*(93) -148 + j*(-98) --89 + j*(-221) --221 + j*(32) -6 + j*(159) -101 + j*(-30) --57 + j*(-80) --86 + j*(57) -13 + j*(91) -62 + j*(70) -149 + j*(31) -168 + j*(-148) --50 + j*(-239) --175 + j*(-48) --16 + j*(45) -9 + j*(-124) --214 + j*(-118) --241 + j*(146) --8 + j*(228) -90 + j*(82) -18 + j*(32) -32 + j*(85) -107 + j*(50) -110 + j*(-39) -56 + j*(-98) --40 + j*(-115) --132 + j*(-23) --74 + j*(122) -91 + j*(100) -89 + j*(-47) --24 + j*(-38) -23 + j*(49) -101 + j*(-47) --33 + j*(-129) --115 + j*(35) -75 + j*(115) -168 + j*(-95) --33 + j*(-216) --160 + j*(-74) --98 + j*(11) --95 + j*(-8) --118 + j*(54) --52 + j*(83) --64 + j*(42) --121 + j*(134) -11 + j*(265) -197 + j*(185) -222 + j*(35) -206 + j*(-37) -188 + j*(-154) -32 + j*(-243) --110 + j*(-148) --96 + j*(-51) --106 + j*(-40) --139 + j*(66) -8 + j*(163) -144 + j*(21) -14 + j*(-112) --97 + j*(24) -70 + j*(129) -204 + j*(-57) -37 + j*(-243) --178 + j*(-142) --157 + j*(46) --51 + j*(66) --57 + j*(59) -1 + j*(157) -222 + j*(100) -239 + j*(-216) --88 + j*(-344) --288 + j*(-112) --199 + j*(47) --189 + j*(48) --208 + j*(198) -13 + j*(298) -150 + j*(100) --20 + j*(11) --41 + j*(216) -219 + j*(242) -327 + j*(5) -231 + j*(-164) -106 + j*(-264) --136 + j*(-272) --288 + j*(7) --48 + j*(240) -183 + j*(67) -69 + j*(-98) -8 + j*(-6) -122 + j*(-62) --15 + j*(-235) --255 + j*(-78) --135 + j*(192) -119 + j*(133) -104 + j*(-75) --58 + j*(-89) --105 + j*(45) -6 + j*(143) -162 + j*(75) -156 + j*(-111) --13 + j*(-154) --62 + j*(-30) -33 + j*(-12) -28 + j*(-91) --11 + j*(-88) -13 + j*(-136) --122 + j*(-258) --389 + j*(-124) --364 + j*(233) --42 + j*(342) -110 + j*(139) -2 + j*(38) --25 + j*(129) -90 + j*(124) -81 + j*(5) --28 + j*(35) -36 + j*(149) -177 + j*(70) -100 + j*(-72) --10 + j*(13) -117 + j*(105) -227 + j*(-49) -110 + j*(-186) -2 + j*(-158) --42 + j*(-147) --136 + j*(-84) --80 + j*(61) -59 + j*(-19) --93 + j*(-139) --214 + j*(105) -108 + j*(238) -248 + j*(-132) --146 + j*(-269) --270 + j*(115) -57 + j*(209) -85 + j*(-21) --40 + j*(62) -174 + j*(110) -185 + j*(-214) --194 + j*(-202) --136 + j*(186) -248 + j*(59) -61 + j*(-331) --327 + j*(-134) --161 + j*(205) -70 + j*(64) --84 + j*(-35) --82 + j*(168) -170 + j*(116) -105 + j*(-159) --163 + j*(-94) --102 + j*(147) -100 + j*(89) -31 + j*(-79) --114 + j*(4) --25 + j*(144) -112 + j*(64) -41 + j*(-65) --84 + j*(9) --18 + j*(151) -137 + j*(129) -190 + j*(9) -163 + j*(-89) -85 + j*(-173) --68 + j*(-154) --93 + j*(26) -119 + j*(64) -183 + j*(-209) --139 + j*(-343) --365 + j*(-29) --107 + j*(252) -180 + j*(51) -11 + j*(-232) --279 + j*(-96) --200 + j*(193) -42 + j*(170) -37 + j*(-5) --93 + j*(13) --81 + j*(137) -21 + j*(187) -158 + j*(174) -303 + j*(-10) -155 + j*(-324) --275 + j*(-277) --348 + j*(180) -57 + j*(327) -197 + j*(1) --89 + j*(-71) --107 + j*(244) -254 + j*(283) -382 + j*(-61) -137 + j*(-263) --69 + j*(-141) --19 + j*(32) -138 + j*(8) -135 + j*(-159) --20 + j*(-175) --9 + j*(-51) -126 + j*(-153) --52 + j*(-384) --409 + j*(-234) --389 + j*(165) --78 + j*(276) -81 + j*(133) -94 + j*(11) -42 + j*(-99) --103 + j*(-112) --155 + j*(25) --57 + j*(74) --47 + j*(23) --64 + j*(69) -36 + j*(51) --16 + j*(-105) --230 + j*(-46) --211 + j*(189) --51 + j*(221) --39 + j*(208) -67 + j*(312) -308 + j*(188) -240 + j*(-112) --30 + j*(-91) --16 + j*(126) -153 + j*(117) -170 + j*(12) -156 + j*(-11) -173 + j*(-64) -130 + j*(-112) -123 + j*(-123) -100 + j*(-220) --86 + j*(-247) --170 + j*(-43) -21 + j*(40) -64 + j*(-161) --175 + j*(-176) --196 + j*(100) -91 + j*(138) -151 + j*(-144) --111 + j*(-234) --230 + j*(-19) --85 + j*(96) --11 + j*(9) --78 + j*(-10) --66 + j*(57) --17 + j*(30) --70 + j*(21) --45 + j*(133) -139 + j*(109) -154 + j*(-121) --70 + j*(-189) --165 + j*(-28) --98 + j*(46) --93 + j*(60) --33 + j*(136) -93 + j*(59) --5 + j*(-81) --144 + j*(55) -36 + j*(194) -176 + j*(-16) --49 + j*(-146) --166 + j*(75) -32 + j*(179) -109 + j*(33) -25 + j*(9) -74 + j*(42) -80 + j*(-77) --93 + j*(-79) --105 + j*(128) -111 + j*(162) -170 + j*(-36) --4 + j*(-98) --60 + j*(74) -142 + j*(148) -281 + j*(-80) -70 + j*(-296) --184 + j*(-135) --49 + j*(103) -166 + j*(-62) --46 + j*(-301) --354 + j*(-80) --202 + j*(281) -147 + j*(244) -206 + j*(-15) -78 + j*(-109) -20 + j*(-95) --17 + j*(-116) --112 + j*(-98) --159 + j*(30) --44 + j*(146) -110 + j*(66) -59 + j*(-88) --69 + j*(-35) -13 + j*(67) -104 + j*(-51) --37 + j*(-129) --83 + j*(6) -40 + j*(-13) --67 + j*(-129) --181 + j*(74) -120 + j*(185) -238 + j*(-213) --223 + j*(-363) --411 + j*(107) --2 + j*(288) -109 + j*(-43) --169 + j*(-46) --73 + j*(214) -182 + j*(56) --7 + j*(-186) --223 + j*(5) --57 + j*(177) -38 + j*(27) --137 + j*(19) --122 + j*(259) -152 + j*(303) -272 + j*(86) --58 + j*(-93) --100 + j*(0) --47 + j*(62) --12 + j*(48) --19 + j*(68) -38 + j*(112) -134 + j*(77) -177 + j*(-38) -98 + j*(-164) --70 + j*(-146) --91 + j*(26) -86 + j*(44) -100 + j*(-155) --105 + j*(-187) --153 + j*(-31) --88 + j*(-11) --148 + j*(4) --104 + j*(144) -77 + j*(93) -1 + j*(-83) --163 + j*(29) --42 + j*(179) -59 + j*(88) -6 + j*(103) -173 + j*(161) -295 + j*(-125) --27 + j*(-320) --240 + j*(-48) --51 + j*(89) --64 + j*(-56) --240 + j*(108) --5 + j*(366) -302 + j*(178) -229 + j*(-81) -117 + j*(-100) -71 + j*(-159) --107 + j*(-115) --44 + j*(127) -263 + j*(4) -87 + j*(-390) --380 + j*(-223) --282 + j*(247) -94 + j*(209) -51 + j*(-11) --28 + j*(110) -204 + j*(122) -228 + j*(-181) --72 + j*(-256) --180 + j*(-27) --45 + j*(78) -35 + j*(24) -47 + j*(-24) -25 + j*(-95) --91 + j*(-107) --139 + j*(34) -9 + j*(113) -112 + j*(-32) --18 + j*(-163) --177 + j*(-57) --107 + j*(117) -78 + j*(79) -77 + j*(-130) --155 + j*(-194) --317 + j*(21) --192 + j*(254) -25 + j*(245) -75 + j*(124) -42 + j*(116) -113 + j*(134) -172 + j*(31) -92 + j*(-42) -69 + j*(21) -177 + j*(-21) -120 + j*(-209) --117 + j*(-191) --136 + j*(36) -48 + j*(42) -5 + j*(-117) --158 + j*(-22) --24 + j*(159) -185 + j*(-5) -11 + j*(-269) --325 + j*(-140) --317 + j*(235) --3 + j*(373) -219 + j*(210) -212 + j*(26) -151 + j*(-43) -105 + j*(-101) --23 + j*(-127) --122 + j*(30) -38 + j*(196) -255 + j*(71) -202 + j*(-150) -57 + j*(-155) -62 + j*(-115) -39 + j*(-182) --60 + j*(-165) --47 + j*(-109) --64 + j*(-175) --222 + j*(-132) --204 + j*(82) -8 + j*(83) -1 + j*(-105) --180 + j*(-86) --175 + j*(76) --64 + j*(91) --54 + j*(36) --90 + j*(42) --106 + j*(91) --60 + j*(166) -63 + j*(159) -100 + j*(40) -21 + j*(1) -16 + j*(33) -9 + j*(-4) --69 + j*(47) -34 + j*(168) -188 + j*(21) -13 + j*(-138) --121 + j*(76) -148 + j*(175) -223 + j*(-135) --93 + j*(-193) --115 + j*(88) -107 + j*(58) -14 + j*(-93) --54 + j*(69) -182 + j*(64) -148 + j*(-245) --184 + j*(-229) --210 + j*(34) --93 + j*(59) --148 + j*(106) --1 + j*(295) -303 + j*(149) -215 + j*(-178) --49 + j*(-133) -8 + j*(54) -163 + j*(-39) -81 + j*(-192) --59 + j*(-179) --118 + j*(-100) --118 + j*(-17) --53 + j*(13) --23 + j*(-49) --103 + j*(-74) --150 + j*(24) --73 + j*(118) -40 + j*(91) -52 + j*(-34) --111 + j*(-65) --180 + j*(177) -151 + j*(338) -451 + j*(-25) -139 + j*(-444) --315 + j*(-242) --226 + j*(152) -42 + j*(132) -35 + j*(14) -57 + j*(62) -177 + j*(-66) --3 + j*(-282) --297 + j*(-113) --188 + j*(219) -132 + j*(180) -148 + j*(-101) --95 + j*(-163) --209 + j*(33) --90 + j*(197) -86 + j*(182) -173 + j*(62) -156 + j*(-76) -34 + j*(-168) --134 + j*(-119) --182 + j*(73) --31 + j*(220) -190 + j*(178) -297 + j*(-51) -141 + j*(-304) --197 + j*(-269) --278 + j*(76) -25 + j*(207) -144 + j*(-59) --113 + j*(-132) --148 + j*(136) -122 + j*(145) -107 + j*(-110) --127 + j*(-78) --93 + j*(135) -77 + j*(127) -96 + j*(30) -80 + j*(14) -95 + j*(-9) -99 + j*(-38) -117 + j*(-107) -3 + j*(-215) --190 + j*(-97) --77 + j*(134) -146 + j*(0) --30 + j*(-206) --221 + j*(6) -1 + j*(166) -99 + j*(-44) --90 + j*(-54) --4 + j*(112) -129 + j*(-68) --141 + j*(-153) --177 + j*(202) -255 + j*(204) -247 + j*(-276) --231 + j*(-282) --257 + j*(129) -39 + j*(151) -18 + j*(-12) --31 + j*(76) -124 + j*(52) -65 + j*(-145) --137 + j*(-75) --69 + j*(94) -24 + j*(14) --105 + j*(13) --45 + j*(247) -314 + j*(206) -386 + j*(-235) --34 + j*(-457) --368 + j*(-156) --218 + j*(197) -83 + j*(174) -133 + j*(-45) -3 + j*(-134) --103 + j*(-102) --164 + j*(-21) --149 + j*(93) --49 + j*(140) -1 + j*(98) --2 + j*(107) -66 + j*(122) -112 + j*(45) -75 + j*(13) -108 + j*(7) -89 + j*(-122) --135 + j*(-112) --146 + j*(194) -220 + j*(252) -347 + j*(-121) -47 + j*(-301) --122 + j*(-133) --78 + j*(-59) --132 + j*(-39) --121 + j*(107) -43 + j*(123) -65 + j*(3) -0 + j*(6) -28 + j*(19) --25 + j*(-3) --30 + j*(155) -253 + j*(176) -336 + j*(-194) --51 + j*(-327) --173 + j*(32) -180 + j*(102) -216 + j*(-272) --151 + j*(-323) --221 + j*(-20) -2 + j*(30) -21 + j*(-152) --139 + j*(-194) --252 + j*(-92) --257 + j*(56) --141 + j*(144) --59 + j*(66) --171 + j*(40) --189 + j*(245) -78 + j*(329) -228 + j*(83) -52 + j*(-64) --35 + j*(65) -88 + j*(93) -81 + j*(-29) --19 + j*(4) -51 + j*(73) -91 + j*(-49) --89 + j*(-61) --86 + j*(194) -256 + j*(208) -338 + j*(-194) --61 + j*(-372) --310 + j*(-57) --134 + j*(196) -39 + j*(155) -78 + j*(124) -184 + j*(71) -158 + j*(-110) --35 + j*(-86) -41 + j*(105) -264 + j*(-45) -71 + j*(-322) --231 + j*(-133) --52 + j*(143) -177 + j*(-59) --62 + j*(-261) --265 + j*(-12) --57 + j*(189) -100 + j*(47) -11 + j*(-28) -30 + j*(59) -171 + j*(-17) -115 + j*(-232) --136 + j*(-275) --298 + j*(-68) --198 + j*(163) -26 + j*(162) -63 + j*(-18) --88 + j*(-41) --87 + j*(114) -82 + j*(100) -62 + j*(-83) --148 + j*(-65) --165 + j*(178) -78 + j*(281) -283 + j*(105) -230 + j*(-146) -14 + j*(-204) --83 + j*(-59) -19 + j*(8) -47 + j*(-107) --103 + j*(-122) --119 + j*(39) -34 + j*(43) -8 + j*(-108) --144 + j*(-64) --92 + j*(64) --23 + j*(-25) --202 + j*(-58) --268 + j*(207) --1 + j*(356) -174 + j*(184) -100 + j*(89) -133 + j*(158) -271 + j*(72) -241 + j*(-103) -148 + j*(-155) -100 + j*(-218) --76 + j*(-274) --255 + j*(-100) --162 + j*(118) --14 + j*(100) --36 + j*(74) -29 + j*(173) -219 + j*(96) -190 + j*(-135) --16 + j*(-155) --52 + j*(0) -69 + j*(35) -124 + j*(-68) -57 + j*(-160) --52 + j*(-144) --59 + j*(-53) -17 + j*(-84) --78 + j*(-204) --276 + j*(-84) --190 + j*(167) -47 + j*(124) -13 + j*(-64) --138 + j*(-23) --124 + j*(95) --76 + j*(151) -35 + j*(229) -257 + j*(121) -202 + j*(-192) --126 + j*(-186) --129 + j*(104) -112 + j*(78) -50 + j*(-122) --115 + j*(-42) --47 + j*(78) -13 + j*(50) -39 + j*(70) -154 + j*(0) -69 + j*(-195) --146 + j*(-127) --76 + j*(21) --59 + j*(-121) --358 + j*(-37) --269 + j*(436) -284 + j*(436) -382 + j*(-49) -68 + j*(-164) -28 + j*(-40) -11 + j*(-114) --161 + j*(-1) -25 + j*(226) -277 + j*(-13) -2 + j*(-267) --229 + j*(18) -38 + j*(206) -164 + j*(-23) --12 + j*(-69) -23 + j*(59) -113 + j*(-27) -19 + j*(-70) -52 + j*(20) -153 + j*(-98) -1 + j*(-229) --131 + j*(-111) --78 + j*(-48) --129 + j*(-68) --166 + j*(77) -5 + j*(139) -53 + j*(0) --34 + j*(21) -91 + j*(74) -140 + j*(-159) --173 + j*(-236) --292 + j*(107) -22 + j*(258) -171 + j*(2) --24 + j*(-113) --100 + j*(34) -14 + j*(82) -34 + j*(-3) --37 + j*(-2) --23 + j*(80) -86 + j*(86) -136 + j*(-40) -23 + j*(-136) --95 + j*(-59) --56 + j*(43) -0 + j*(30) --11 + j*(40) -77 + j*(76) -170 + j*(-75) -3 + j*(-244) --219 + j*(-118) --163 + j*(91) --27 + j*(72) --74 + j*(15) --110 + j*(128) -45 + j*(200) -165 + j*(61) -72 + j*(-80) --64 + j*(-24) --37 + j*(105) -81 + j*(119) -138 + j*(49) -156 + j*(-16) -142 + j*(-117) -9 + j*(-184) --108 + j*(-65) --1 + j*(55) -105 + j*(-69) --52 + j*(-182) --187 + j*(-1) --2 + j*(153) -178 + j*(-25) -27 + j*(-255) --250 + j*(-187) --313 + j*(76) --156 + j*(240) --13 + j*(222) -21 + j*(215) -143 + j*(276) -366 + j*(147) -343 + j*(-151) -117 + j*(-214) -105 + j*(-119) -141 + j*(-264) --132 + j*(-344) --269 + j*(-49) --8 + j*(69) -23 + j*(-182) --247 + j*(-142) --164 + j*(129) -55 + j*(-15) --192 + j*(-189) --375 + j*(148) --27 + j*(369) -183 + j*(85) --32 + j*(-37) --41 + j*(161) -185 + j*(100) -115 + j*(-148) --120 + j*(-119) --140 + j*(70) --25 + j*(124) -41 + j*(73) -18 + j*(6) --73 + j*(35) --45 + j*(182) -153 + j*(185) -195 + j*(-16) -21 + j*(-59) -9 + j*(117) -218 + j*(127) -294 + j*(-98) -137 + j*(-260) --60 + j*(-227) --136 + j*(-63) --22 + j*(70) -148 + j*(-11) -111 + j*(-217) --107 + j*(-260) --231 + j*(-105) --192 + j*(38) --115 + j*(89) --54 + j*(93) --22 + j*(81) -1 + j*(84) -52 + j*(76) -77 + j*(13) -37 + j*(-25) -25 + j*(8) -88 + j*(-7) -87 + j*(-119) --45 + j*(-185) --189 + j*(-96) --198 + j*(83) --51 + j*(183) -87 + j*(113) -77 + j*(4) -25 + j*(16) -90 + j*(40) -155 + j*(-81) -42 + j*(-221) --137 + j*(-199) --225 + j*(-76) --243 + j*(45) --204 + j*(182) --61 + j*(288) -133 + j*(248) -224 + j*(81) -153 + j*(-76) -4 + j*(-97) --74 + j*(21) -14 + j*(138) -168 + j*(95) -193 + j*(-69) -64 + j*(-153) --27 + j*(-81) -20 + j*(-16) -66 + j*(-81) --18 + j*(-142) --101 + j*(-75) --67 + j*(-4) --41 + j*(-32) --103 + j*(-24) --98 + j*(81) -29 + j*(103) -74 + j*(-22) --47 + j*(-78) --127 + j*(41) --26 + j*(160) -125 + j*(113) -160 + j*(-31) -75 + j*(-139) --60 + j*(-154) --174 + j*(-51) --153 + j*(119) -6 + j*(189) -113 + j*(96) -94 + j*(30) -121 + j*(30) -172 + j*(-88) -10 + j*(-219) --187 + j*(-54) --39 + j*(184) -237 + j*(52) -151 + j*(-251) --156 + j*(-244) --231 + j*(13) --58 + j*(145) -87 + j*(50) -42 + j*(-88) --91 + j*(-62) --61 + j*(79) -98 + j*(30) -33 + j*(-157) --182 + j*(-86) --115 + j*(130) -73 + j*(50) --46 + j*(-101) --185 + j*(64) -5 + j*(214) -159 + j*(35) -18 + j*(-108) --103 + j*(-11) --60 + j*(83) --4 + j*(95) -47 + j*(91) -85 + j*(33) -40 + j*(-16) -4 + j*(17) -15 + j*(41) -26 + j*(81) -150 + j*(123) -303 + j*(-62) -138 + j*(-344) --212 + j*(-277) --256 + j*(30) --73 + j*(128) --6 + j*(70) -5 + j*(75) -61 + j*(65) -85 + j*(18) -101 + j*(-24) -77 + j*(-115) --62 + j*(-132) --110 + j*(13) -10 + j*(68) -47 + j*(-10) -30 + j*(-11) -99 + j*(-71) --31 + j*(-247) --332 + j*(-99) --231 + j*(294) -177 + j*(280) -240 + j*(-62) -8 + j*(-164) --102 + j*(-46) --88 + j*(66) -23 + j*(156) -206 + j*(66) -171 + j*(-167) --32 + j*(-187) --60 + j*(-83) --61 + j*(-118) --185 + j*(-63) --129 + j*(107) -15 + j*(49) --84 + j*(-28) --100 + j*(136) -112 + j*(112) -54 + j*(-110) --141 + j*(-11) -1 + j*(137) -76 + j*(-54) --173 + j*(-47) --104 + j*(264) -245 + j*(156) -110 + j*(-190) --223 + j*(-24) --37 + j*(310) -304 + j*(158) -242 + j*(-159) --3 + j*(-188) --87 + j*(-29) -23 + j*(78) -160 + j*(-24) -63 + j*(-215) --173 + j*(-147) --156 + j*(84) -15 + j*(103) -30 + j*(21) -25 + j*(35) -62 + j*(-1) -10 + j*(-11) -81 + j*(68) -237 + j*(-103) -16 + j*(-366) --320 + j*(-170) --194 + j*(140) -1 + j*(51) --114 + j*(-6) --73 + j*(151) -81 + j*(52) --91 + j*(-49) --141 + j*(226) -212 + j*(274) -280 + j*(-65) -42 + j*(-98) -131 + j*(21) -194 + j*(-222) --152 + j*(-291) --223 + j*(76) -125 + j*(115) -122 + j*(-217) --176 + j*(-213) --190 + j*(-3) --119 + j*(-14) --219 + j*(14) --203 + j*(210) --6 + j*(287) -149 + j*(202) -209 + j*(55) -133 + j*(-83) -2 + j*(-46) -74 + j*(49) -179 + j*(-95) -3 + j*(-258) --199 + j*(-132) --170 + j*(35) --119 + j*(71) --83 + j*(136) -38 + j*(141) -54 + j*(34) --25 + j*(61) -61 + j*(153) -182 + j*(53) -131 + j*(-63) -85 + j*(-67) -73 + j*(-127) --61 + j*(-151) --122 + j*(-9) --18 + j*(52) -4 + j*(-5) --14 + j*(23) -58 + j*(1) --18 + j*(-116) --194 + j*(16) --37 + j*(268) -283 + j*(143) -243 + j*(-203) --57 + j*(-267) --205 + j*(-64) --112 + j*(121) -74 + j*(116) -119 + j*(-62) --58 + j*(-122) --123 + j*(66) -80 + j*(141) -176 + j*(-57) -19 + j*(-171) --87 + j*(-83) --71 + j*(-20) --68 + j*(3) --41 + j*(40) --4 + j*(32) --2 + j*(34) -58 + j*(47) -114 + j*(-51) -21 + j*(-151) --78 + j*(-112) --97 + j*(-73) --161 + j*(-37) --148 + j*(109) -38 + j*(129) -73 + j*(-78) --150 + j*(-136) --269 + j*(67) --170 + j*(247) --1 + j*(320) -208 + j*(259) -281 + j*(28) -121 + j*(-89) -81 + j*(-4) -174 + j*(-98) --25 + j*(-274) --297 + j*(-57) --144 + j*(271) -159 + j*(225) -216 + j*(40) -196 + j*(-65) -116 + j*(-190) --76 + j*(-161) --54 + j*(21) -95 + j*(-53) --59 + j*(-198) --228 + j*(7) --27 + j*(187) -124 + j*(35) -44 + j*(-49) -60 + j*(-37) -15 + j*(-174) --230 + j*(-104) --174 + j*(205) -130 + j*(169) -79 + j*(-66) --72 + j*(47) -117 + j*(155) -221 + j*(-62) -61 + j*(-147) -62 + j*(-91) -47 + j*(-239) --243 + j*(-231) --281 + j*(124) -54 + j*(195) -121 + j*(-86) --101 + j*(-129) --133 + j*(22) --74 + j*(42) --87 + j*(78) -10 + j*(142) -106 + j*(36) -32 + j*(-50) -4 + j*(-21) --4 + j*(-89) --188 + j*(-73) --204 + j*(218) -144 + j*(295) -277 + j*(-48) --11 + j*(-194) --123 + j*(30) -61 + j*(74) -34 + j*(-107) --177 + j*(-31) --98 + j*(231) -204 + j*(197) -244 + j*(-111) --33 + j*(-225) --197 + j*(-1) --30 + j*(187) -153 + j*(67) -63 + j*(-95) --81 + j*(-9) -12 + j*(141) -190 + j*(67) -177 + j*(-129) -13 + j*(-197) --107 + j*(-113) --117 + j*(-1) --60 + j*(71) -23 + j*(88) -100 + j*(35) -88 + j*(-69) --11 + j*(-82) --11 + j*(6) -96 + j*(-40) -5 + j*(-206) --248 + j*(-99) --163 + j*(227) -199 + j*(185) -191 + j*(-167) --119 + j*(-162) --76 + j*(105) -180 + j*(8) -55 + j*(-266) --228 + j*(-161) --160 + j*(80) -11 + j*(8) --114 + j*(-124) --274 + j*(42) --139 + j*(257) -96 + j*(208) -119 + j*(18) --11 + j*(-27) --40 + j*(74) -57 + j*(83) -52 + j*(-25) --79 + j*(-2) --48 + j*(165) -156 + j*(155) -175 + j*(-50) --1 + j*(-70) -21 + j*(83) -192 + j*(18) -117 + j*(-190) --97 + j*(-135) --58 + j*(47) -81 + j*(-12) --18 + j*(-130) --134 + j*(4) -12 + j*(124) -128 + j*(-17) -5 + j*(-112) --49 + j*(-5) -57 + j*(1) -31 + j*(-127) --113 + j*(-108) --129 + j*(9) --81 + j*(48) --56 + j*(81) -28 + j*(83) -38 + j*(-24) --100 + j*(-11) --66 + j*(181) -176 + j*(162) -204 + j*(-91) -9 + j*(-158) --65 + j*(-59) --69 + j*(-22) --90 + j*(67) -57 + j*(156) -198 + j*(-14) -37 + j*(-180) --115 + j*(-44) -4 + j*(60) -52 + j*(-54) --56 + j*(-61) --39 + j*(26) --1 + j*(-2) --39 + j*(29) -76 + j*(92) -187 + j*(-96) --28 + j*(-264) --224 + j*(-92) --122 + j*(61) --80 + j*(-1) --158 + j*(60) --59 + j*(183) -66 + j*(103) -13 + j*(32) -11 + j*(85) -72 + j*(45) -11 + j*(-5) --17 + j*(65) -42 + j*(86) -44 + j*(95) -161 + j*(163) -363 + j*(-30) -178 + j*(-357) --187 + j*(-235) --96 + j*(74) -130 + j*(-52) --52 + j*(-229) --209 + j*(-28) --30 + j*(89) -23 + j*(-59) --107 + j*(-59) --92 + j*(40) --68 + j*(20) --115 + j*(91) -22 + j*(194) -168 + j*(57) -70 + j*(-71) -26 + j*(-2) -120 + j*(-66) --8 + j*(-235) --249 + j*(-124) --223 + j*(129) --40 + j*(185) -47 + j*(116) -68 + j*(49) -35 + j*(-7) --30 + j*(8) --28 + j*(79) -33 + j*(113) -123 + j*(102) -204 + j*(-24) -76 + j*(-203) --170 + j*(-90) --69 + j*(195) -245 + j*(95) -158 + j*(-240) --174 + j*(-190) --177 + j*(107) -42 + j*(163) -142 + j*(49) -151 + j*(-68) -50 + j*(-195) --172 + j*(-136) --173 + j*(142) -119 + j*(221) -278 + j*(-36) -114 + j*(-250) --102 + j*(-200) --130 + j*(-32) --1 + j*(11) -24 + j*(-122) --148 + j*(-151) --196 + j*(33) --47 + j*(76) --72 + j*(-30) --170 + j*(101) -50 + j*(231) -221 + j*(-35) --45 + j*(-224) --215 + j*(4) --42 + j*(105) --57 + j*(-28) --194 + j*(96) --16 + j*(271) -156 + j*(112) -44 + j*(19) -76 + j*(128) -238 + j*(-6) -78 + j*(-228) --148 + j*(-119) --98 + j*(23) --104 + j*(-27) --246 + j*(102) --106 + j*(381) -239 + j*(347) -337 + j*(71) -212 + j*(-62) -150 + j*(-42) -183 + j*(-61) -163 + j*(-170) -12 + j*(-219) --98 + j*(-71) -46 + j*(55) -183 + j*(-117) --18 + j*(-289) --238 + j*(-91) --73 + j*(152) -176 + j*(39) -127 + j*(-198) --57 + j*(-233) --146 + j*(-152) --180 + j*(-85) --200 + j*(1) --144 + j*(107) -1 + j*(119) -73 + j*(-41) --114 + j*(-161) --310 + j*(48) --119 + j*(334) -217 + j*(216) -178 + j*(-86) --22 + j*(-79) -32 + j*(16) -74 + j*(-133) --153 + j*(-197) --279 + j*(30) --129 + j*(180) --37 + j*(119) --78 + j*(130) --8 + j*(230) -156 + j*(186) -185 + j*(20) -64 + j*(-52) -2 + j*(38) -104 + j*(86) -163 + j*(-53) -3 + j*(-146) --120 + j*(19) -37 + j*(163) -194 + j*(24) -87 + j*(-128) --36 + j*(-46) -44 + j*(45) -132 + j*(-40) -68 + j*(-155) --65 + j*(-154) --138 + j*(-47) --95 + j*(70) -10 + j*(97) -74 + j*(43) -95 + j*(-16) -81 + j*(-103) --44 + j*(-167) --199 + j*(-45) --132 + j*(197) -158 + j*(233) -322 + j*(-40) -137 + j*(-305) --164 + j*(-239) --192 + j*(28) -18 + j*(87) -59 + j*(-82) --100 + j*(-79) --55 + j*(91) -147 + j*(14) -74 + j*(-220) --156 + j*(-181) --140 + j*(-11) --47 + j*(-61) --153 + j*(-135) --257 + j*(-30) --238 + j*(66) --244 + j*(126) --209 + j*(260) --46 + j*(312) -22 + j*(236) -9 + j*(281) -201 + j*(363) -430 + j*(145) -317 + j*(-176) -32 + j*(-187) --30 + j*(-4) -60 + j*(49) -90 + j*(29) -136 + j*(47) -245 + j*(-40) -196 + j*(-244) --38 + j*(-298) --174 + j*(-123) --88 + j*(11) --17 + j*(-28) --68 + j*(-49) --83 + j*(29) --5 + j*(65) -43 + j*(22) -53 + j*(-15) -59 + j*(-69) --15 + j*(-142) --151 + j*(-98) --187 + j*(67) --66 + j*(193) -110 + j*(187) -238 + j*(45) -207 + j*(-169) -2 + j*(-263) --160 + j*(-136) --109 + j*(12) --6 + j*(-22) --65 + j*(-117) --212 + j*(-54) --209 + j*(144) --12 + j*(242) -166 + j*(105) -113 + j*(-104) --93 + j*(-127) --184 + j*(53) --57 + j*(207) -129 + j*(167) -175 + j*(4) -84 + j*(-77) -45 + j*(-45) -97 + j*(-89) -6 + j*(-246) --279 + j*(-209) --381 + j*(130) --100 + j*(376) -206 + j*(229) -187 + j*(-40) --4 + j*(-87) --64 + j*(35) -8 + j*(90) -42 + j*(54) -29 + j*(59) -69 + j*(88) -132 + j*(49) -135 + j*(-20) -111 + j*(-54) -91 + j*(-91) -34 + j*(-111) --1 + j*(-77) -13 + j*(-76) --38 + j*(-104) --95 + j*(-18) -4 + j*(59) -75 + j*(-46) --35 + j*(-94) --40 + j*(23) -91 + j*(-29) --1 + j*(-185) --167 + j*(-86) --81 + j*(33) --61 + j*(-68) --223 + j*(7) --105 + j*(243) -148 + j*(127) -32 + j*(-69) --72 + j*(95) -171 + j*(127) -173 + j*(-175) --131 + j*(-167) --89 + j*(83) -95 + j*(-29) --90 + j*(-171) --210 + j*(43) --22 + j*(119) --40 + j*(-27) --184 + j*(100) -2 + j*(282) -200 + j*(127) -130 + j*(-17) -111 + j*(-9) -117 + j*(-129) --94 + j*(-177) --190 + j*(54) -12 + j*(165) -109 + j*(14) -8 + j*(-57) --64 + j*(-12) --117 + j*(70) --55 + j*(274) -291 + j*(320) -506 + j*(-68) -216 + j*(-407) --111 + j*(-269) --52 + j*(-72) -22 + j*(-175) --177 + j*(-229) --292 + j*(14) --74 + j*(188) -116 + j*(2) --67 + j*(-202) --332 + j*(-25) --221 + j*(295) -78 + j*(299) -143 + j*(116) -87 + j*(101) -180 + j*(128) -279 + j*(-5) -235 + j*(-170) -111 + j*(-284) --101 + j*(-310) --286 + j*(-110) --165 + j*(149) -86 + j*(95) -54 + j*(-112) --113 + j*(-77) --71 + j*(54) -33 + j*(-2) --43 + j*(-102) --169 + j*(-28) --141 + j*(131) -21 + j*(176) -119 + j*(57) -62 + j*(-42) -23 + j*(-21) -62 + j*(-74) --66 + j*(-185) --256 + j*(-33) --129 + j*(194) -70 + j*(87) --54 + j*(-48) --144 + j*(112) -21 + j*(165) -12 + j*(29) --115 + j*(135) -61 + j*(291) -226 + j*(127) -120 + j*(44) -197 + j*(144) -371 + j*(-76) -93 + j*(-339) --199 + j*(-67) -62 + j*(204) -298 + j*(-40) -105 + j*(-233) --4 + j*(-117) -64 + j*(-120) --18 + j*(-175) --41 + j*(-80) -53 + j*(-147) --121 + j*(-286) --337 + j*(-67) --146 + j*(177) -47 + j*(35) --89 + j*(-62) --99 + j*(100) -95 + j*(51) -17 + j*(-166) --212 + j*(-88) --161 + j*(119) --18 + j*(93) --62 + j*(25) --94 + j*(119) -40 + j*(178) -163 + j*(55) -100 + j*(-137) --139 + j*(-170) --284 + j*(79) --76 + j*(322) -199 + j*(191) -124 + j*(-40) --28 + j*(47) -128 + j*(159) -260 + j*(-51) -57 + j*(-220) --107 + j*(-76) --18 + j*(35) -21 + j*(-42) --72 + j*(-40) --78 + j*(76) -26 + j*(135) -158 + j*(83) -202 + j*(-102) -0 + j*(-253) --227 + j*(-74) --90 + j*(181) -142 + j*(74) -46 + j*(-95) --36 + j*(17) -120 + j*(2) -25 + j*(-218) --256 + j*(-74) --93 + j*(234) -197 + j*(65) -5 + j*(-176) --179 + j*(49) -68 + j*(189) -176 + j*(-54) --35 + j*(-127) --68 + j*(35) -38 + j*(34) -17 + j*(-4) -62 + j*(30) -120 + j*(-97) --59 + j*(-191) --181 + j*(-20) --69 + j*(86) --48 + j*(62) --11 + j*(187) -285 + j*(157) -341 + j*(-256) --76 + j*(-428) --305 + j*(-126) --152 + j*(51) --106 + j*(-14) --175 + j*(42) --112 + j*(139) --47 + j*(139) --3 + j*(173) -124 + j*(151) -150 + j*(21) -98 + j*(-5) -159 + j*(-37) -103 + j*(-225) --169 + j*(-203) --190 + j*(72) -42 + j*(92) -26 + j*(-97) --136 + j*(-57) --112 + j*(64) --71 + j*(72) --46 + j*(134) -115 + j*(112) -98 + j*(-119) --182 + j*(-112) --197 + j*(175) -30 + j*(197) --2 + j*(75) --61 + j*(226) -189 + j*(305) -315 + j*(74) -192 + j*(-13) -255 + j*(34) -334 + j*(-185) -63 + j*(-341) --110 + j*(-105) -100 + j*(14) -175 + j*(-221) --57 + j*(-315) --185 + j*(-172) --187 + j*(-81) --210 + j*(38) --52 + j*(190) -195 + j*(50) -103 + j*(-244) --187 + j*(-214) --216 + j*(17) --74 + j*(57) --68 + j*(-6) --95 + j*(25) --50 + j*(40) --60 + j*(-6) --115 + j*(25) --94 + j*(90) --54 + j*(87) --71 + j*(102) --31 + j*(175) -88 + j*(174) -153 + j*(68) -116 + j*(-25) -47 + j*(-53) --10 + j*(-28) --8 + j*(33) -66 + j*(31) -66 + j*(-81) --95 + j*(-101) --158 + j*(102) -57 + j*(216) -211 + j*(13) -25 + j*(-153) --134 + j*(28) -48 + j*(187) -210 + j*(25) -92 + j*(-111) -34 + j*(-24) -149 + j*(-68) -56 + j*(-260) --198 + j*(-196) --202 + j*(29) --91 + j*(60) --122 + j*(81) --25 + j*(231) -221 + j*(131) -146 + j*(-146) --112 + j*(-62) -26 + j*(181) -291 + j*(2) -134 + j*(-296) --140 + j*(-214) --124 + j*(-47) --105 + j*(-64) --187 + j*(31) --49 + j*(195) -172 + j*(66) -89 + j*(-181) --160 + j*(-173) --251 + j*(30) --158 + j*(216) -66 + j*(269) -252 + j*(84) -152 + j*(-173) --115 + j*(-153) --155 + j*(78) -22 + j*(159) -121 + j*(59) -110 + j*(-18) -107 + j*(-64) -78 + j*(-160) --71 + j*(-231) --272 + j*(-127) --298 + j*(153) --40 + j*(322) -209 + j*(154) -129 + j*(-89) --78 + j*(-45) --30 + j*(139) -154 + j*(100) -146 + j*(-78) -5 + j*(-105) --30 + j*(-6) -42 + j*(25) -78 + j*(-33) -49 + j*(-81) -10 + j*(-93) --25 + j*(-88) --45 + j*(-66) --37 + j*(-63) --71 + j*(-98) --168 + j*(-62) --174 + j*(75) --57 + j*(114) --51 + j*(44) --114 + j*(128) -53 + j*(245) -244 + j*(46) -56 + j*(-189) --183 + j*(-27) --54 + j*(180) -86 + j*(95) -33 + j*(69) -147 + j*(130) -258 + j*(-103) --43 + j*(-267) --233 + j*(59) -105 + j*(238) -250 + j*(-105) --94 + j*(-200) --133 + j*(144) -221 + j*(134) -185 + j*(-224) --156 + j*(-179) --106 + j*(123) -157 + j*(67) -100 + j*(-156) --79 + j*(-107) --30 + j*(28) -83 + j*(-28) -36 + j*(-136) --61 + j*(-124) --77 + j*(-66) --62 + j*(-59) --79 + j*(-62) --92 + j*(-49) --110 + j*(-57) --182 + j*(-35) --214 + j*(95) --91 + j*(204) -60 + j*(141) -56 + j*(3) --45 + j*(-40) --129 + j*(17) --141 + j*(137) --25 + j*(233) -122 + j*(161) -86 + j*(21) --23 + j*(67) -54 + j*(190) -211 + j*(124) -212 + j*(-29) -135 + j*(-88) -77 + j*(-112) --6 + j*(-95) --18 + j*(2) -88 + j*(3) -71 + j*(-130) --93 + j*(-113) --89 + j*(60) -63 + j*(59) -40 + j*(-63) --64 + j*(4) -46 + j*(124) -199 + j*(3) -110 + j*(-165) --14 + j*(-121) -27 + j*(-78) --1 + j*(-172) --158 + j*(-121) --114 + j*(62) -56 + j*(11) --25 + j*(-129) --136 + j*(-5) -47 + j*(67) -91 + j*(-194) --243 + j*(-243) --317 + j*(116) -11 + j*(177) -3 + j*(-127) --325 + j*(-47) --234 + j*(315) -100 + j*(265) -64 + j*(33) --65 + j*(122) -97 + j*(205) -181 + j*(7) --6 + j*(-79) --92 + j*(75) -12 + j*(163) -88 + j*(139) -138 + j*(116) -185 + j*(54) -168 + j*(-6) -181 + j*(-8) -240 + j*(-107) -139 + j*(-284) --102 + j*(-268) --188 + j*(-57) --70 + j*(79) -58 + j*(59) -124 + j*(-29) -103 + j*(-166) --71 + j*(-239) --239 + j*(-76) --129 + j*(154) -112 + j*(103) -102 + j*(-105) --44 + j*(-100) -5 + j*(-24) -39 + j*(-165) --192 + j*(-214) --280 + j*(54) --28 + j*(146) -11 + j*(-100) --272 + j*(-77) --240 + j*(257) -103 + j*(257) -129 + j*(-45) --126 + j*(-84) --192 + j*(124) --57 + j*(243) -98 + j*(217) -176 + j*(70) -47 + j*(-66) --117 + j*(63) -3 + j*(264) -213 + j*(202) -236 + j*(78) -286 + j*(42) -349 + j*(-157) -115 + j*(-352) --127 + j*(-173) -20 + j*(19) -157 + j*(-155) --40 + j*(-293) --196 + j*(-150) --152 + j*(-35) --146 + j*(-13) --134 + j*(73) --30 + j*(105) -13 + j*(47) -10 + j*(41) -62 + j*(22) -60 + j*(-71) --35 + j*(-108) --110 + j*(-59) --139 + j*(27) --74 + j*(130) -66 + j*(100) -47 + j*(-45) --98 + j*(-1) --24 + j*(165) -166 + j*(89) -119 + j*(-95) --11 + j*(-73) -14 + j*(-10) -33 + j*(-52) --2 + j*(-54) -25 + j*(-62) --21 + j*(-153) --182 + j*(-127) --233 + j*(45) --139 + j*(170) -1 + j*(206) -148 + j*(111) -108 + j*(-99) --129 + j*(-91) --134 + j*(153) -90 + j*(165) -76 + j*(2) --10 + j*(93) -205 + j*(142) -282 + j*(-177) --66 + j*(-310) --218 + j*(-15) -1 + j*(78) --14 + j*(-107) --235 + j*(-4) --125 + j*(271) -153 + j*(228) -177 + j*(35) -113 + j*(18) -173 + j*(6) -194 + j*(-136) -57 + j*(-248) --127 + j*(-214) --227 + j*(-45) --142 + j*(150) -74 + j*(161) -149 + j*(-24) -10 + j*(-123) --74 + j*(-17) -27 + j*(42) -69 + j*(-86) --99 + j*(-143) --210 + j*(53) --30 + j*(233) -194 + j*(115) -153 + j*(-89) -27 + j*(-88) -62 + j*(-47) -72 + j*(-163) --100 + j*(-204) --189 + j*(-44) --81 + j*(39) --68 + j*(-37) --172 + j*(21) --89 + j*(191) -129 + j*(135) -123 + j*(-83) --49 + j*(-111) --71 + j*(-8) --25 + j*(-44) --149 + j*(-86) --254 + j*(98) --92 + j*(288) -134 + j*(214) -148 + j*(37) -54 + j*(-8) -28 + j*(28) -52 + j*(37) -73 + j*(12) -54 + j*(-32) -0 + j*(-33) --11 + j*(12) -13 + j*(13) --25 + j*(10) --30 + j*(112) -132 + j*(161) -252 + j*(-8) -144 + j*(-168) -29 + j*(-141) -30 + j*(-132) --53 + j*(-196) --215 + j*(-105) --197 + j*(113) --7 + j*(194) -131 + j*(92) -123 + j*(-40) -34 + j*(-86) --18 + j*(-30) -45 + j*(15) -116 + j*(-76) -27 + j*(-212) --169 + j*(-191) --255 + j*(8) --118 + j*(182) -92 + j*(132) -102 + j*(-62) --54 + j*(-100) --85 + j*(8) --28 + j*(4) --95 + j*(-16) --102 + j*(118) -75 + j*(128) -71 + j*(-64) --132 + j*(-17) --40 + j*(214) -228 + j*(106) -140 + j*(-165) --86 + j*(-104) --25 + j*(43) -59 + j*(-49) --69 + j*(-115) --153 + j*(-3) --126 + j*(90) --95 + j*(182) -64 + j*(298) -332 + j*(189) -383 + j*(-132) -158 + j*(-334) --75 + j*(-292) --163 + j*(-157) --159 + j*(-76) --169 + j*(-34) --181 + j*(57) --85 + j*(127) --28 + j*(52) --142 + j*(67) --79 + j*(303) -290 + j*(274) -351 + j*(-153) --33 + j*(-279) --140 + j*(3) -62 + j*(5) --73 + j*(-185) --316 + j*(36) --100 + j*(343) -207 + j*(205) -150 + j*(-18) -44 + j*(9) -76 + j*(36) -62 + j*(19) -93 + j*(89) -264 + j*(37) -279 + j*(-225) -16 + j*(-364) --221 + j*(-199) --173 + j*(59) -66 + j*(86) -129 + j*(-153) --130 + j*(-253) --272 + j*(4) --43 + j*(154) -59 + j*(-58) --181 + j*(-96) --188 + j*(203) -158 + j*(231) -231 + j*(-121) --78 + j*(-242) --231 + j*(-1) --73 + j*(164) -84 + j*(79) -61 + j*(-66) --76 + j*(-97) --165 + j*(21) --100 + j*(154) -40 + j*(170) -131 + j*(82) -130 + j*(-43) -13 + j*(-129) --132 + j*(-51) --111 + j*(118) -43 + j*(163) -134 + j*(69) -128 + j*(-24) -84 + j*(-93) --4 + j*(-115) --61 + j*(-58) --43 + j*(-29) --78 + j*(-49) --159 + j*(25) --115 + j*(165) -18 + j*(211) -129 + j*(172) -212 + j*(86) -221 + j*(-52) -125 + j*(-137) -45 + j*(-125) -16 + j*(-107) --10 + j*(-80) -27 + j*(-62) -37 + j*(-163) --149 + j*(-210) --275 + j*(22) --55 + j*(215) -170 + j*(40) -67 + j*(-195) --156 + j*(-200) --302 + j*(-58) --322 + j*(194) --71 + j*(402) -238 + j*(243) -168 + j*(-30) -2 + j*(40) -160 + j*(127) -233 + j*(-122) --49 + j*(-212) --134 + j*(47) -83 + j*(91) -67 + j*(-90) --89 + j*(-14) -31 + j*(129) -164 + j*(5) -69 + j*(-88) -65 + j*(-21) -152 + j*(-116) -13 + j*(-266) --174 + j*(-155) --125 + j*(-5) --59 + j*(-30) --108 + j*(-16) --58 + j*(72) -64 + j*(13) -32 + j*(-130) --104 + j*(-166) --220 + j*(-107) --293 + j*(26) --243 + j*(204) --74 + j*(280) -58 + j*(226) -134 + j*(148) -170 + j*(0) -11 + j*(-155) --245 + j*(-18) --176 + j*(311) -156 + j*(342) -262 + j*(116) -193 + j*(44) -262 + j*(13) -243 + j*(-202) --38 + j*(-252) --123 + j*(7) -99 + j*(65) -106 + j*(-138) --89 + j*(-102) --18 + j*(80) -149 + j*(-20) -48 + j*(-172) --64 + j*(-101) --25 + j*(-78) --115 + j*(-115) --180 + j*(65) -54 + j*(159) -156 + j*(-105) --135 + j*(-199) --218 + j*(101) -74 + j*(163) -98 + j*(-118) --190 + j*(-112) --197 + j*(192) -77 + j*(262) -214 + j*(89) -193 + j*(-59) -103 + j*(-161) --49 + j*(-148) --66 + j*(-4) -71 + j*(-13) -25 + j*(-175) --161 + j*(-125) --121 + j*(42) --14 + j*(-19) --148 + j*(-78) --216 + j*(136) -24 + j*(252) -177 + j*(52) -52 + j*(-83) --16 + j*(-22) -18 + j*(-40) --71 + j*(-76) --123 + j*(59) -44 + j*(127) -129 + j*(-62) --69 + j*(-186) --238 + j*(-18) --142 + j*(175) -23 + j*(151) -30 + j*(36) --66 + j*(38) --69 + j*(160) -87 + j*(211) -202 + j*(57) -70 + j*(-105) --125 + j*(11) --36 + j*(258) -256 + j*(247) -360 + j*(-23) -197 + j*(-205) -21 + j*(-161) --1 + j*(-37) -98 + j*(21) -211 + j*(-69) -178 + j*(-262) --44 + j*(-342) --214 + j*(-179) --140 + j*(-1) --15 + j*(-43) --81 + j*(-137) --187 + j*(-45) --99 + j*(74) -3 + j*(-13) --115 + j*(-96) --217 + j*(71) --26 + j*(221) -170 + j*(42) -25 + j*(-180) --197 + j*(-85) --160 + j*(109) --40 + j*(117) --26 + j*(94) -37 + j*(112) -98 + j*(-15) --82 + j*(-117) --240 + j*(110) --1 + j*(338) -275 + j*(139) -134 + j*(-122) --68 + j*(-4) -70 + j*(153) -226 + j*(2) -109 + j*(-165) --36 + j*(-118) --52 + j*(-29) --26 + j*(29) -66 + j*(57) -154 + j*(-70) -16 + j*(-228) --197 + j*(-118) --143 + j*(106) -51 + j*(93) -57 + j*(-57) --50 + j*(-73) --76 + j*(-7) --59 + j*(15) --70 + j*(35) --49 + j*(91) -35 + j*(104) -85 + j*(16) --7 + j*(-52) --91 + j*(71) -88 + j*(199) -296 + j*(-21) -82 + j*(-317) --267 + j*(-149) --164 + j*(194) -119 + j*(135) -63 + j*(-51) --30 + j*(45) -124 + j*(87) -167 + j*(-99) -21 + j*(-161) --25 + j*(-115) --90 + j*(-147) --234 + j*(-19) --102 + j*(209) -148 + j*(103) -43 + j*(-117) --130 + j*(21) -50 + j*(173) -204 + j*(-17) -57 + j*(-162) --29 + j*(-80) -25 + j*(-93) --62 + j*(-186) --221 + j*(-114) --245 + j*(52) --156 + j*(170) --15 + j*(185) -43 + j*(71) --71 + j*(38) --92 + j*(211) -127 + j*(278) -246 + j*(107) -192 + j*(24) -250 + j*(10) -283 + j*(-182) -70 + j*(-308) --66 + j*(-182) --13 + j*(-148) --116 + j*(-216) --252 + j*(-37) --62 + j*(138) -112 + j*(-57) --100 + j*(-228) --281 + j*(-28) --136 + j*(136) --43 + j*(33) --157 + j*(18) --152 + j*(171) --5 + j*(194) -13 + j*(103) --39 + j*(147) -66 + j*(231) -209 + j*(132) -166 + j*(-13) -83 + j*(9) -156 + j*(37) -194 + j*(-104) -38 + j*(-194) --76 + j*(-85) --24 + j*(-7) --20 + j*(-30) --55 + j*(39) -60 + j*(112) -179 + j*(-3) -111 + j*(-139) -19 + j*(-146) --33 + j*(-150) --140 + j*(-105) --130 + j*(66) -59 + j*(73) -48 + j*(-127) --174 + j*(-85) --111 + j*(163) -148 + j*(89) -57 + j*(-166) --199 + j*(-43) --42 + j*(231) -268 + j*(74) -163 + j*(-266) --154 + j*(-243) --196 + j*(-18) --93 + j*(25) --111 + j*(3) --117 + j*(85) --22 + j*(112) --1 + j*(53) --16 + j*(87) -100 + j*(93) -138 + j*(-99) --95 + j*(-192) --242 + j*(38) --50 + j*(209) -101 + j*(59) --30 + j*(-54) --123 + j*(69) --38 + j*(158) -14 + j*(148) -58 + j*(201) -231 + j*(191) -325 + j*(-23) -185 + j*(-195) -45 + j*(-173) -7 + j*(-163) --122 + j*(-169) --247 + j*(42) --34 + j*(297) -319 + j*(155) -280 + j*(-231) --61 + j*(-281) --139 + j*(-29) -41 + j*(18) -45 + j*(-135) --93 + j*(-124) --81 + j*(-28) --38 + j*(-63) --110 + j*(-82) --141 + j*(-9) --116 + j*(16) --156 + j*(40) --140 + j*(154) --14 + j*(196) -58 + j*(135) -78 + j*(104) -120 + j*(43) -58 + j*(-41) --25 + j*(34) -86 + j*(121) -199 + j*(-7) -112 + j*(-131) -44 + j*(-110) -33 + j*(-158) --121 + j*(-179) --187 + j*(18) -6 + j*(85) -30 + j*(-119) --228 + j*(-107) --243 + j*(201) -52 + j*(291) -208 + j*(91) -141 + j*(-68) -42 + j*(-112) --58 + j*(-93) --100 + j*(0) --47 + j*(62) --12 + j*(48) --19 + j*(68) -38 + j*(112) -134 + j*(77) -177 + j*(-38) -98 + j*(-164) --70 + j*(-146) --91 + j*(26) -86 + j*(44) -100 + j*(-155) --105 + j*(-187) --153 + j*(-31) --88 + j*(-11) --148 + j*(4) --104 + j*(144) -77 + j*(93) -1 + j*(-83) --163 + j*(29) --42 + j*(179) -59 + j*(88) -6 + j*(103) -173 + j*(161) -295 + j*(-125) --27 + j*(-320) --240 + j*(-48) --51 + j*(89) --64 + j*(-56) --240 + j*(108) --5 + j*(366) -302 + j*(178) -229 + j*(-81) -117 + j*(-100) -71 + j*(-159) --107 + j*(-115) --44 + j*(127) -263 + j*(4) -87 + j*(-390) --380 + j*(-223) --282 + j*(247) -94 + j*(209) -51 + j*(-11) --28 + j*(110) -204 + j*(122) -228 + j*(-181) --72 + j*(-256) --180 + j*(-27) --45 + j*(78) -35 + j*(24) -47 + j*(-24) -25 + j*(-95) --91 + j*(-107) --139 + j*(34) -9 + j*(113) -112 + j*(-32) --18 + j*(-163) --177 + j*(-57) --107 + j*(117) -78 + j*(79) -77 + j*(-130) --155 + j*(-194) --317 + j*(21) --192 + j*(254) -25 + j*(245) -75 + j*(124) -42 + j*(116) -113 + j*(134) -172 + j*(31) -92 + j*(-42) -69 + j*(21) -177 + j*(-21) -120 + j*(-209) --117 + j*(-191) --136 + j*(36) -48 + j*(42) -5 + j*(-117) --158 + j*(-22) --24 + j*(159) -185 + j*(-5) -11 + j*(-269) --325 + j*(-140) --317 + j*(235) --3 + j*(373) -219 + j*(210) -212 + j*(26) -151 + j*(-43) -105 + j*(-101) --23 + j*(-127) --122 + j*(30) -38 + j*(196) -255 + j*(71) -202 + j*(-150) -57 + j*(-155) -62 + j*(-115) -39 + j*(-182) --60 + j*(-165) --47 + j*(-109) --64 + j*(-175) --222 + j*(-132) --204 + j*(82) -8 + j*(83) -1 + j*(-105) --180 + j*(-86) --175 + j*(76) --64 + j*(91) --54 + j*(36) --90 + j*(42) --106 + j*(91) --60 + j*(166) -63 + j*(159) -100 + j*(40) -21 + j*(1) -16 + j*(33) -9 + j*(-4) --69 + j*(47) -34 + j*(168) -188 + j*(21) -13 + j*(-138) --121 + j*(76) -148 + j*(175) -223 + j*(-135) --93 + j*(-193) --115 + j*(88) -107 + j*(58) -14 + j*(-93) --54 + j*(69) -182 + j*(64) -148 + j*(-245) --184 + j*(-229) --210 + j*(34) --93 + j*(59) --148 + j*(106) --1 + j*(295) -303 + j*(149) -215 + j*(-178) --49 + j*(-133) -8 + j*(54) -163 + j*(-39) -81 + j*(-192) --59 + j*(-179) --118 + j*(-100) --118 + j*(-17) -254 + j*(-10) -76 + j*(-153) --18 + j*(-66) -47 + j*(-84) --64 + j*(-223) --321 + j*(-112) --313 + j*(218) --22 + j*(334) -153 + j*(167) -99 + j*(27) -22 + j*(46) -63 + j*(111) -179 + j*(66) -187 + j*(-107) -5 + j*(-195) --132 + j*(-49) --30 + j*(89) -84 + j*(16) -40 + j*(-76) --21 + j*(-76) --74 + j*(-69) --136 + j*(7) --70 + j*(119) -35 + j*(62) --59 + j*(2) --95 + j*(186) -182 + j*(254) -316 + j*(-60) -25 + j*(-243) --161 + j*(4) -49 + j*(172) -197 + j*(2) -77 + j*(-119) -9 + j*(-37) -89 + j*(-21) -93 + j*(-126) --8 + j*(-157) --58 + j*(-104) --63 + j*(-88) --116 + j*(-65) --126 + j*(49) -14 + j*(114) -130 + j*(-16) -37 + j*(-168) --119 + j*(-136) --157 + j*(-20) --112 + j*(59) --28 + j*(83) -31 + j*(3) --67 + j*(-66) --148 + j*(71) -28 + j*(179) -158 + j*(-12) --24 + j*(-141) --117 + j*(20) -31 + j*(50) --12 + j*(-100) --171 + j*(-1) --35 + j*(156) -93 + j*(-4) --98 + j*(-98) --174 + j*(116) -35 + j*(187) -96 + j*(18) --18 + j*(-19) --39 + j*(40) --48 + j*(51) --66 + j*(136) -66 + j*(216) -198 + j*(115) -176 + j*(-5) -137 + j*(-35) -116 + j*(-69) -88 + j*(-67) -142 + j*(-100) -82 + j*(-290) --246 + j*(-293) --373 + j*(76) --87 + j*(290) -103 + j*(158) -93 + j*(109) -226 + j*(86) -247 + j*(-175) --47 + j*(-240) --90 + j*(38) -199 + j*(8) -119 + j*(-333) --255 + j*(-281) --264 + j*(42) --71 + j*(64) --111 + j*(-4) --120 + j*(132) -69 + j*(139) -86 + j*(-52) --85 + j*(-52) --62 + j*(112) -108 + j*(74) -86 + j*(-99) --75 + j*(-96) --78 + j*(42) -48 + j*(34) -23 + j*(-105) --137 + j*(-85) --141 + j*(82) --5 + j*(100) --5 + j*(16) --49 + j*(69) -77 + j*(88) -92 + j*(-113) --182 + j*(-150) --276 + j*(168) -23 + j*(330) -208 + j*(107) -64 + j*(-23) -19 + j*(103) -180 + j*(107) -218 + j*(-68) -98 + j*(-160) -4 + j*(-145) --81 + j*(-99) --108 + j*(50) -88 + j*(154) -288 + j*(-64) -101 + j*(-367) --256 + j*(-279) --276 + j*(37) --73 + j*(96) --68 + j*(-6) --135 + j*(78) -10 + j*(161) -100 + j*(9) --40 + j*(-54) --47 + j*(86) -120 + j*(31) -17 + j*(-182) --261 + j*(-69) --202 + j*(252) -85 + j*(308) -233 + j*(171) -313 + j*(39) -313 + j*(-197) -59 + j*(-351) --148 + j*(-180) --38 + j*(-49) --19 + j*(-190) --227 + j*(-170) --216 + j*(52) --65 + j*(30) --182 + j*(-33) --238 + j*(215) -83 + j*(325) -241 + j*(23) -12 + j*(-115) --50 + j*(55) -91 + j*(32) --6 + j*(-98) --127 + j*(57) -63 + j*(179) -190 + j*(-16) -9 + j*(-130) --76 + j*(42) -98 + j*(110) -183 + j*(-63) -37 + j*(-179) --99 + j*(-83) --46 + j*(57) -93 + j*(35) -106 + j*(-106) --13 + j*(-163) --94 + j*(-113) --136 + j*(-58) --165 + j*(54) --32 + j*(177) -162 + j*(64) -71 + j*(-158) --149 + j*(-78) --66 + j*(133) -136 + j*(49) -71 + j*(-140) --71 + j*(-119) --86 + j*(-66) --157 + j*(-65) --223 + j*(89) --69 + j*(231) -83 + j*(136) -29 + j*(52) -28 + j*(136) -187 + j*(112) -212 + j*(-88) -43 + j*(-182) --72 + j*(-89) --44 + j*(-6) --4 + j*(-25) --49 + j*(-52) --112 + j*(14) --66 + j*(126) -68 + j*(138) -146 + j*(37) -121 + j*(-84) --1 + j*(-151) --154 + j*(-57) --107 + j*(158) -141 + j*(159) -177 + j*(-77) --22 + j*(-104) -13 + j*(62) -192 + j*(-56) -21 + j*(-290) --262 + j*(-132) --165 + j*(151) -51 + j*(113) -37 + j*(-5) -8 + j*(18) -48 + j*(-3) -5 + j*(-36) -13 + j*(17) -94 + j*(-44) --9 + j*(-171) --174 + j*(-58) --77 + j*(116) -74 + j*(33) --8 + j*(-82) --98 + j*(-1) --31 + j*(72) -20 + j*(40) -21 + j*(30) -64 + j*(12) -51 + j*(-73) --57 + j*(-83) --91 + j*(29) -23 + j*(86) -109 + j*(-33) --9 + j*(-166) --200 + j*(-70) --149 + j*(159) -74 + j*(156) -83 + j*(-26) --53 + j*(5) -53 + j*(127) -204 + j*(-57) --27 + j*(-267) --308 + j*(-41) --140 + j*(284) -176 + j*(204) -175 + j*(-47) -9 + j*(-84) --35 + j*(17) -29 + j*(69) -103 + j*(41) -121 + j*(-43) -66 + j*(-91) -41 + j*(-82) -42 + j*(-129) --63 + j*(-180) --174 + j*(-76) --117 + j*(28) --91 + j*(-16) --206 + j*(47) --128 + j*(283) -193 + j*(266) -258 + j*(-54) --4 + j*(-167) --118 + j*(26) -6 + j*(127) -75 + j*(84) -110 + j*(81) -209 + j*(21) -190 + j*(-151) -24 + j*(-204) --61 + j*(-107) --36 + j*(-48) --18 + j*(-37) -16 + j*(-31) -38 + j*(-91) --39 + j*(-144) --117 + j*(-92) --119 + j*(-35) --132 + j*(4) --97 + j*(93) -38 + j*(78) -30 + j*(-82) --153 + j*(-69) --146 + j*(127) -32 + j*(129) -7 + j*(-2) --95 + j*(94) -70 + j*(228) -284 + j*(57) -206 + j*(-215) --42 + j*(-288) --244 + j*(-165) --298 + j*(76) --113 + j*(277) -151 + j*(194) -148 + j*(-52) --52 + j*(-83) --88 + j*(83) -62 + j*(131) -139 + j*(-5) -27 + j*(-122) --129 + j*(-40) --79 + j*(156) -146 + j*(141) -173 + j*(-105) --63 + j*(-176) --173 + j*(10) --83 + j*(117) --54 + j*(129) --1 + j*(231) -201 + j*(235) -281 + j*(44) -183 + j*(-27) -228 + j*(15) -324 + j*(-140) -168 + j*(-317) -9 + j*(-233) -95 + j*(-191) -66 + j*(-401) --260 + j*(-458) --479 + j*(-179) --404 + j*(89) --280 + j*(207) --132 + j*(310) -119 + j*(280) -226 + j*(27) -56 + j*(-135) --73 + j*(-43) --4 + j*(4) --29 + j*(-98) --199 + j*(-45) --175 + j*(177) -49 + j*(215) -124 + j*(40) -13 + j*(-30) --31 + j*(44) -29 + j*(79) -76 + j*(40) -74 + j*(-19) -21 + j*(-52) --27 + j*(-10) -15 + j*(32) -49 + j*(-23) --18 + j*(-55) --40 + j*(7) -6 + j*(-1) --54 + j*(-41) --117 + j*(76) -35 + j*(183) -183 + j*(40) -79 + j*(-119) --56 + j*(-58) --21 + j*(38) -50 + j*(14) -41 + j*(-52) --28 + j*(-80) --106 + j*(-21) --86 + j*(90) -12 + j*(117) -50 + j*(80) -88 + j*(90) -192 + j*(17) -143 + j*(-177) --98 + j*(-196) --193 + j*(33) --33 + j*(197) -168 + j*(150) -250 + j*(-32) -138 + j*(-204) --47 + j*(-156) -9 + j*(-8) -151 + j*(-147) --70 + j*(-351) --349 + j*(-124) --182 + j*(161) -18 + j*(32) --139 + j*(-53) --158 + j*(165) -86 + j*(170) -72 + j*(-34) --64 + j*(42) -110 + j*(148) -255 + j*(-100) -24 + j*(-322) --247 + j*(-218) --320 + j*(-6) --276 + j*(197) --72 + j*(337) -158 + j*(236) -158 + j*(52) -81 + j*(40) -131 + j*(45) -138 + j*(-57) -52 + j*(-81) -54 + j*(-54) -50 + j*(-128) --89 + j*(-151) --167 + j*(-4) --62 + j*(112) -55 + j*(58) -35 + j*(-46) --64 + j*(-44) --78 + j*(58) -19 + j*(84) -42 + j*(1) --32 + j*(1) --6 + j*(69) -49 + j*(25) --19 + j*(8) -16 + j*(121) -192 + j*(54) -127 + j*(-167) --102 + j*(-120) --66 + j*(75) -74 + j*(30) -8 + j*(-43) -1 + j*(54) -139 + j*(17) -100 + j*(-153) --66 + j*(-147) --98 + j*(-37) --68 + j*(16) --15 + j*(61) -84 + j*(8) -28 + j*(-129) --129 + j*(-59) --46 + j*(98) -94 + j*(-8) --35 + j*(-121) --118 + j*(24) -33 + j*(71) -48 + j*(-83) --100 + j*(-80) --98 + j*(34) --57 + j*(25) --103 + j*(65) --9 + j*(173) -144 + j*(78) -78 + j*(-78) --37 + j*(-34) -0 + j*(20) --2 + j*(-29) --74 + j*(18) --7 + j*(117) -107 + j*(59) -73 + j*(-45) -1 + j*(-21) -39 + j*(28) -100 + j*(-18) -72 + j*(-114) --42 + j*(-136) --112 + j*(-36) --37 + j*(57) -66 + j*(1) -25 + j*(-115) --92 + j*(-118) --153 + j*(-37) --148 + j*(53) --81 + j*(117) -6 + j*(95) --6 + j*(8) --119 + j*(34) --115 + j*(215) -116 + j*(305) -327 + j*(112) -244 + j*(-161) -6 + j*(-180) --41 + j*(-23) -54 + j*(-16) -8 + j*(-91) --58 + j*(-13) -45 + j*(30) -57 + j*(-109) --122 + j*(-103) --122 + j*(91) -43 + j*(95) -12 + j*(-2) --17 + j*(115) -218 + j*(117) -244 + j*(-215) --125 + j*(-296) --244 + j*(61) -66 + j*(191) -192 + j*(-68) --1 + j*(-185) --94 + j*(-71) --57 + j*(-23) --71 + j*(-9) --31 + j*(62) -89 + j*(21) -81 + j*(-135) --74 + j*(-192) --194 + j*(-103) --212 + j*(11) --192 + j*(98) --140 + j*(192) --10 + j*(256) -150 + j*(190) -185 + j*(32) -104 + j*(-49) -66 + j*(-52) -30 + j*(-100) --106 + j*(-81) --137 + j*(122) -101 + j*(227) -299 + j*(7) -167 + j*(-274) --129 + j*(-287) --291 + j*(-65) --211 + j*(175) -12 + j*(243) -161 + j*(110) -141 + j*(-30) -76 + j*(-87) -0 + j*(-122) --113 + j*(-66) --84 + j*(83) -66 + j*(64) -27 + j*(-73) --97 + j*(8) -37 + j*(119) -139 + j*(-71) --106 + j*(-170) --213 + j*(111) -76 + j*(228) -186 + j*(-36) --42 + j*(-121) --96 + j*(71) -56 + j*(107) -79 + j*(19) -66 + j*(16) -92 + j*(-28) -16 + j*(-65) -13 + j*(39) -163 + j*(-16) -59 + j*(-238) --233 + j*(-105) --89 + j*(243) -305 + j*(105) -205 + j*(-313) --194 + j*(-281) --226 + j*(44) --6 + j*(103) -47 + j*(-24) --11 + j*(-57) --18 + j*(-42) --17 + j*(-63) --56 + j*(-95) --145 + j*(-77) --183 + j*(60) --34 + j*(148) -72 + j*(-6) --105 + j*(-104) --199 + j*(105) -18 + j*(197) -80 + j*(-12) --137 + j*(-14) --93 + j*(242) -199 + j*(199) -197 + j*(-86) --37 + j*(-129) --113 + j*(28) --45 + j*(131) -69 + j*(158) -174 + j*(63) -106 + j*(-69) --1 + j*(5) -128 + j*(93) -242 + j*(-97) -55 + j*(-266) --127 + j*(-158) --124 + j*(-42) --134 + j*(18) --73 + j*(149) -127 + j*(127) -139 + j*(-74) --11 + j*(-93) --3 + j*(-16) -10 + j*(-75) --98 + j*(-40) --27 + j*(89) -96 + j*(-18) --55 + j*(-123) --149 + j*(67) -45 + j*(164) -137 + j*(19) -86 + j*(-37) -105 + j*(-89) --21 + j*(-194) --181 + j*(-13) -57 + j*(156) -234 + j*(-164) --155 + j*(-371) --403 + j*(13) --110 + j*(256) -44 + j*(81) --47 + j*(73) -78 + j*(133) -125 + j*(-73) --116 + j*(-96) --110 + j*(153) -117 + j*(132) -90 + j*(-28) -31 + j*(24) -131 + j*(-12) -42 + j*(-148) --80 + j*(-46) -35 + j*(4) --16 + j*(-148) --221 + j*(-10) --23 + j*(239) -247 + j*(18) -35 + j*(-240) --163 + j*(-67) --24 + j*(13) --80 + j*(-137) --294 + j*(2) --169 + j*(264) -54 + j*(219) -59 + j*(127) -112 + j*(136) -174 + j*(1) -14 + j*(-87) --62 + j*(85) -124 + j*(143) -178 + j*(-30) -48 + j*(-71) -57 + j*(12) -126 + j*(-59) -17 + j*(-147) --106 + j*(-33) --15 + j*(132) -194 + j*(95) -240 + j*(-132) -50 + j*(-254) --88 + j*(-122) -29 + j*(-28) -99 + j*(-187) --95 + j*(-300) --267 + j*(-153) --228 + j*(6) --156 + j*(41) --122 + j*(45) --116 + j*(18) --200 + j*(42) --203 + j*(222) -21 + j*(305) -157 + j*(124) -35 + j*(19) -1 + j*(133) -151 + j*(129) -161 + j*(-35) -23 + j*(-59) -8 + j*(44) -104 + j*(49) -136 + j*(-48) -61 + j*(-132) --68 + j*(-103) --92 + j*(47) -61 + j*(115) -170 + j*(-22) -78 + j*(-151) --27 + j*(-126) --45 + j*(-93) --95 + j*(-88) --137 + j*(16) --23 + j*(93) -66 + j*(-27) --81 + j*(-129) --231 + j*(39) --94 + j*(255) -139 + j*(207) -181 + j*(49) -168 + j*(5) -231 + j*(-105) -105 + j*(-317) --192 + j*(-274) --228 + j*(-6) --57 + j*(23) --119 + j*(-89) --247 + j*(63) --71 + j*(233) -102 + j*(82) --31 + j*(-52) --136 + j*(80) --28 + j*(187) -78 + j*(155) -148 + j*(89) -148 + j*(-62) --52 + j*(-130) --185 + j*(100) -29 + j*(301) -266 + j*(177) -280 + j*(9) -292 + j*(-85) -248 + j*(-291) --40 + j*(-396) --267 + j*(-170) --177 + j*(76) --1 + j*(95) -80 + j*(14) -73 + j*(-90) --40 + j*(-127) --90 + j*(-12) -42 + j*(26) -76 + j*(-139) --103 + j*(-202) --210 + j*(-71) --193 + j*(36) --164 + j*(129) --33 + j*(216) -126 + j*(130) -117 + j*(-5) -87 + j*(-40) -73 + j*(-141) --123 + j*(-200) --259 + j*(21) --77 + j*(185) -45 + j*(64) --32 + j*(29) -25 + j*(78) -39 + j*(-61) --186 + j*(-27) --119 + j*(289) -267 + j*(222) -222 + j*(-170) --119 + j*(-139) --74 + j*(124) -100 + j*(53) -10 + j*(-36) -6 + j*(71) -132 + j*(1) -15 + j*(-147) --148 + j*(-28) --78 + j*(127) -16 + j*(134) -77 + j*(156) -214 + j*(111) -246 + j*(-65) -144 + j*(-152) -95 + j*(-178) --23 + j*(-248) --216 + j*(-129) --152 + j*(127) -95 + j*(122) -135 + j*(-69) -17 + j*(-143) --75 + j*(-119) --157 + j*(-23) --88 + j*(161) -169 + j*(155) -256 + j*(-113) -64 + j*(-281) --111 + j*(-223) --162 + j*(-124) --154 + j*(-61) --140 + j*(-59) --221 + j*(-59) --289 + j*(105) --129 + j*(254) -20 + j*(151) --62 + j*(88) --39 + j*(217) -130 + j*(165) -64 + j*(25) --11 + j*(163) -244 + j*(229) -377 + j*(-88) -127 + j*(-293) --59 + j*(-196) --95 + j*(-131) --170 + j*(-47) --93 + j*(93) -25 + j*(1) --151 + j*(-75) --233 + j*(204) -87 + j*(337) -245 + j*(80) -103 + j*(-13) -141 + j*(52) -190 + j*(-105) --16 + j*(-148) --7 + j*(62) -220 + j*(-32) -76 + j*(-298) --201 + j*(-168) --111 + j*(37) --32 + j*(-49) --175 + j*(-12) --93 + j*(198) -136 + j*(139) -124 + j*(-34) -64 + j*(-37) -95 + j*(-90) --20 + j*(-189) --171 + j*(-74) --114 + j*(78) --15 + j*(88) -44 + j*(83) -137 + j*(1) -63 + j*(-166) --142 + j*(-103) --74 + j*(103) -123 + j*(6) --6 + j*(-195) --221 + j*(-57) --105 + j*(156) -79 + j*(72) -19 + j*(-69) --80 + j*(-19) --35 + j*(44) -6 + j*(-13) --87 + j*(-61) --192 + j*(52) --112 + j*(243) -129 + j*(253) -236 + j*(35) -91 + j*(-115) --44 + j*(-27) -28 + j*(87) -164 + j*(11) -116 + j*(-182) --134 + j*(-210) --259 + j*(60) --3 + j*(262) -236 + j*(19) --20 + j*(-234) --297 + j*(56) -16 + j*(375) -365 + j*(76) -103 + j*(-260) --189 + j*(-14) -66 + j*(234) -293 + j*(-16) -82 + j*(-218) --50 + j*(-61) -93 + j*(-19) -71 + j*(-188) --122 + j*(-160) --113 + j*(14) -15 + j*(16) -16 + j*(-71) --30 + j*(-85) --64 + j*(-98) --147 + j*(-69) --159 + j*(56) --42 + j*(100) --10 + j*(16) --82 + j*(27) --41 + j*(112) -51 + j*(78) -37 + j*(17) -42 + j*(22) -63 + j*(-54) --76 + j*(-110) --168 + j*(71) -37 + j*(191) -164 + j*(-25) --70 + j*(-147) --192 + j*(117) -93 + j*(267) -295 + j*(3) -106 + j*(-244) --141 + j*(-170) --177 + j*(23) --72 + j*(125) -36 + j*(92) -20 + j*(3) --78 + j*(56) -6 + j*(214) -238 + j*(158) -263 + j*(-87) -98 + j*(-170) -50 + j*(-124) -33 + j*(-194) --156 + j*(-219) --292 + j*(2) --151 + j*(224) -63 + j*(221) -158 + j*(116) -206 + j*(26) -218 + j*(-108) -115 + j*(-239) --49 + j*(-247) --142 + j*(-158) --155 + j*(-78) --161 + j*(-39) --186 + j*(23) --165 + j*(136) --27 + j*(216) -141 + j*(137) -158 + j*(-59) --6 + j*(-153) --134 + j*(-54) --101 + j*(64) --33 + j*(65) --40 + j*(52) --20 + j*(94) -48 + j*(69) -9 + j*(-5) --81 + j*(67) -15 + j*(206) -206 + j*(132) -190 + j*(-62) -49 + j*(-74) -56 + j*(9) -117 + j*(-29) -82 + j*(-70) -109 + j*(-51) -172 + j*(-185) --23 + j*(-366) --314 + j*(-216) --270 + j*(88) --56 + j*(100) --87 + j*(-6) --153 + j*(111) -8 + j*(194) -96 + j*(55) -1 + j*(24) -62 + j*(109) -177 + j*(-33) --5 + j*(-171) --139 + j*(36) -106 + j*(148) -213 + j*(-146) --103 + j*(-272) --249 + j*(13) --27 + j*(144) -54 + j*(-21) --76 + j*(-47) --66 + j*(56) --2 + j*(21) --71 + j*(-16) --115 + j*(82) --36 + j*(163) -71 + j*(156) -151 + j*(59) -82 + j*(-78) --102 + j*(-16) --26 + j*(233) -302 + j*(174) -305 + j*(-202) --49 + j*(-272) --136 + j*(16) -96 + j*(71) -115 + j*(-139) --86 + j*(-150) --104 + j*(27) -35 + j*(42) -37 + j*(-70) --75 + j*(-55) --54 + j*(78) -115 + j*(75) -156 + j*(-124) --50 + j*(-234) --222 + j*(-63) --117 + j*(148) -104 + j*(119) -156 + j*(-89) --21 + j*(-228) --242 + j*(-114) --213 + j*(168) -88 + j*(238) -245 + j*(-41) -39 + j*(-260) --187 + j*(-162) --201 + j*(-8) --169 + j*(58) --125 + j*(132) --17 + j*(139) -13 + j*(47) --62 + j*(23) --98 + j*(83) --105 + j*(158) --29 + j*(301) -257 + j*(325) -447 + j*(-21) -163 + j*(-355) --231 + j*(-200) --208 + j*(164) -71 + j*(241) -204 + j*(75) -139 + j*(-61) -31 + j*(-52) -40 + j*(45) -155 + j*(26) -152 + j*(-117) -21 + j*(-144) --9 + j*(-71) --6 + j*(-77) --78 + j*(-23) -15 + j*(126) -240 + j*(30) -194 + j*(-238) --36 + j*(-265) --91 + j*(-148) --93 + j*(-141) --160 + j*(-93) --126 + j*(-5) --101 + j*(-31) --165 + j*(47) -11 + j*(185) -234 + j*(-70) --75 + j*(-383) --466 + j*(-63) --175 + j*(363) -235 + j*(107) -8 + j*(-264) --322 + j*(-86) --228 + j*(157) --153 + j*(132) --203 + j*(249) -27 + j*(402) -252 + j*(170) -44 + j*(-29) --88 + j*(217) -237 + j*(332) -385 + j*(-18) -80 + j*(-173) --9 + j*(91) -257 + j*(102) -236 + j*(-187) --31 + j*(-152) -47 + j*(62) -228 + j*(-81) -47 + j*(-245) --74 + j*(-57) -150 + j*(-21) -128 + j*(-331) --258 + j*(-325) --310 + j*(66) -21 + j*(145) -88 + j*(-127) --151 + j*(-194) --251 + j*(-11) --170 + j*(112) --82 + j*(139) --10 + j*(121) -11 + j*(64) --31 + j*(62) --7 + j*(124) -93 + j*(112) -126 + j*(6) -42 + j*(-59) --32 + j*(-1) -19 + j*(89) -142 + j*(49) -147 + j*(-100) -18 + j*(-167) --82 + j*(-115) --127 + j*(-44) --140 + j*(68) --24 + j*(180) -145 + j*(122) -173 + j*(-27) -119 + j*(-105) -63 + j*(-177) --92 + j*(-196) --182 + j*(-29) --30 + j*(71) -28 + j*(-77) --143 + j*(-95) --134 + j*(83) -23 + j*(35) --97 + j*(-97) --238 + j*(85) --45 + j*(245) -86 + j*(83) --67 + j*(37) --52 + j*(232) -197 + j*(238) -286 + j*(17) -182 + j*(-133) -50 + j*(-175) --86 + j*(-118) --106 + j*(40) -28 + j*(112) -120 + j*(37) -129 + j*(-43) -112 + j*(-134) --9 + j*(-215) --161 + j*(-141) --180 + j*(-4) --148 + j*(71) --98 + j*(168) -72 + j*(206) -185 + j*(52) -101 + j*(-66) -54 + j*(-49) -39 + j*(-105) --122 + j*(-78) --98 + j*(180) -253 + j*(181) -315 + j*(-221) --54 + j*(-357) --211 + j*(-95) --59 + j*(-6) --71 + j*(-112) --192 + j*(-51) --170 + j*(62) --144 + j*(98) --115 + j*(206) -75 + j*(272) -245 + j*(103) -181 + j*(-96) -48 + j*(-134) --18 + j*(-117) --96 + j*(-97) --159 + j*(6) --98 + j*(127) -32 + j*(123) -52 + j*(21) --45 + j*(25) --13 + j*(169) -207 + j*(154) -260 + j*(-107) -22 + j*(-226) --115 + j*(-51) -6 + j*(68) -105 + j*(-15) -75 + j*(-115) --16 + j*(-165) --156 + j*(-121) --179 + j*(66) -6 + j*(146) -101 + j*(-12) --24 + j*(-93) --80 + j*(9) -5 + j*(45) -41 + j*(-20) -14 + j*(-86) --86 + j*(-133) --232 + j*(-35) --189 + j*(170) --17 + j*(186) --16 + j*(129) -40 + j*(239) -302 + j*(142) -232 + j*(-231) --175 + j*(-193) --135 + j*(192) -209 + j*(107) -62 + j*(-202) --229 + j*(6) -7 + j*(298) -291 + j*(92) -164 + j*(-139) -38 + j*(-79) -85 + j*(-69) -36 + j*(-137) --35 + j*(-97) --25 + j*(-71) --74 + j*(-62) --58 + j*(52) -118 + j*(33) -110 + j*(-211) --180 + j*(-263) --324 + j*(4) --163 + j*(216) -29 + j*(197) -110 + j*(105) -139 + j*(16) -114 + j*(-91) --4 + j*(-152) --122 + j*(-69) --78 + j*(74) -77 + j*(49) -64 + j*(-122) --115 + j*(-130) --146 + j*(22) --57 + j*(50) --74 + j*(18) --73 + j*(103) -56 + j*(91) -34 + j*(-60) --123 + j*(-23) --85 + j*(131) -33 + j*(101) --1 + j*(56) -42 + j*(124) -165 + j*(4) --16 + j*(-183) --284 + j*(33) --88 + j*(383) -301 + j*(281) -313 + j*(-45) -132 + j*(-107) -120 + j*(-59) -117 + j*(-146) --25 + j*(-164) --78 + j*(-21) -50 + j*(42) -121 + j*(-77) -15 + j*(-170) --95 + j*(-87) --25 + j*(22) -95 + j*(-66) --10 + j*(-231) --231 + j*(-156) --216 + j*(67) --58 + j*(75) --108 + j*(-13) --192 + j*(141) -27 + j*(284) -223 + j*(67) -39 + j*(-119) --94 + j*(57) -118 + j*(142) -185 + j*(-107) --74 + j*(-174) --129 + j*(74) -108 + j*(103) -122 + j*(-139) --121 + j*(-174) --208 + j*(45) --54 + j*(185) -111 + j*(119) -115 + j*(-40) --29 + j*(-81) --82 + j*(69) -83 + j*(148) -202 + j*(0) -124 + j*(-132) -52 + j*(-143) -6 + j*(-183) --119 + j*(-177) --158 + j*(-59) --113 + j*(-46) --206 + j*(-45) --221 + j*(156) -25 + j*(206) -66 + j*(-45) --206 + j*(-42) --188 + j*(257) -80 + j*(268) -86 + j*(122) -84 + j*(221) -343 + j*(170) -361 + j*(-197) -23 + j*(-321) --142 + j*(-121) --106 + j*(-8) --95 + j*(71) -39 + j*(152) -164 + j*(8) -15 + j*(-106) --46 + j*(63) -163 + j*(71) -142 + j*(-177) --112 + j*(-150) --83 + j*(72) -87 + j*(40) -53 + j*(-65) -25 + j*(-30) -74 + j*(-76) --7 + j*(-144) --54 + j*(-71) -3 + j*(-107) --147 + j*(-208) --345 + j*(4) --169 + j*(287) -110 + j*(211) -119 + j*(41) -110 + j*(19) -148 + j*(-118) --73 + j*(-258) --314 + j*(-25) --127 + j*(276) -167 + j*(165) -117 + j*(-55) --4 + j*(-7) -100 + j*(40) -143 + j*(-129) --39 + j*(-216) --150 + j*(-91) --101 + j*(-23) --125 + j*(-52) --200 + j*(29) --144 + j*(153) --40 + j*(166) -11 + j*(151) -85 + j*(118) -91 + j*(-7) --61 + j*(-33) --100 + j*(148) -93 + j*(218) -199 + j*(59) -112 + j*(-40) -63 + j*(-27) -28 + j*(-44) --54 + j*(28) -35 + j*(182) -256 + j*(131) -306 + j*(-94) -187 + j*(-243) -21 + j*(-292) --157 + j*(-193) --129 + j*(25) -83 + j*(13) -42 + j*(-211) --204 + j*(-165) --187 + j*(63) --46 + j*(74) --51 + j*(54) -43 + j*(98) -112 + j*(-78) --137 + j*(-135) --150 + j*(200) -284 + j*(163) -214 + j*(-362) --363 + j*(-276) --255 + j*(302) -293 + j*(146) -83 + j*(-375) --423 + j*(-147) --228 + j*(315) -134 + j*(178) -39 + j*(-47) --64 + j*(32) --3 + j*(41) --75 + j*(15) --71 + j*(171) -154 + j*(167) -175 + j*(-86) --69 + j*(-142) --149 + j*(66) -4 + j*(169) -115 + j*(78) -75 + j*(-21) --17 + j*(6) -23 + j*(125) -205 + j*(89) -219 + j*(-150) --26 + j*(-232) --145 + j*(-30) -8 + j*(84) -98 + j*(-42) --12 + j*(-126) --103 + j*(-57) --100 + j*(23) --71 + j*(86) -13 + j*(136) -128 + j*(88) -135 + j*(-43) -35 + j*(-82) -3 + j*(-13) -74 + j*(-7) -74 + j*(-98) --23 + j*(-114) --48 + j*(-29) -23 + j*(-13) -37 + j*(-82) --19 + j*(-112) --54 + j*(-98) --83 + j*(-95) --122 + j*(-71) --146 + j*(-47) --209 + j*(-8) --245 + j*(141) --91 + j*(293) -115 + j*(228) -140 + j*(78) -114 + j*(45) -153 + j*(-23) -64 + j*(-152) --105 + j*(-92) --72 + j*(58) -28 + j*(18) --56 + j*(-42) --107 + j*(85) -36 + j*(156) -123 + j*(37) -47 + j*(-40) -1 + j*(1) -21 + j*(21) -24 + j*(16) -45 + j*(29) -75 + j*(-9) -35 + j*(-57) --26 + j*(-11) -36 + j*(71) -168 + j*(4) -137 + j*(-182) --62 + j*(-215) --121 + j*(-64) --18 + j*(-70) --149 + j*(-198) --399 + j*(23) --184 + j*(413) -272 + j*(271) -185 + j*(-159) --191 + j*(-66) --62 + j*(284) -279 + j*(151) -170 + j*(-151) --56 + j*(-49) -82 + j*(110) -231 + j*(-54) -95 + j*(-223) --56 + j*(-167) --69 + j*(-92) --76 + j*(-71) --86 + j*(-23) --50 + j*(15) --8 + j*(13) -24 + j*(-11) -33 + j*(-72) --23 + j*(-122) --91 + j*(-112) --129 + j*(-92) --197 + j*(-66) --251 + j*(42) --188 + j*(165) --86 + j*(171) --81 + j*(136) --107 + j*(202) --6 + j*(310) -184 + j*(270) -243 + j*(90) -127 + j*(6) -94 + j*(98) -244 + j*(95) -273 + j*(-111) -74 + j*(-185) -13 + j*(-28) -173 + j*(-26) -148 + j*(-244) --113 + j*(-246) --159 + j*(-1) -40 + j*(54) -84 + j*(-108) --50 + j*(-150) --100 + j*(-60) --72 + j*(-21) --64 + j*(3) --14 + j*(33) -53 + j*(-29) -1 + j*(-134) --134 + j*(-132) --203 + j*(-6) --136 + j*(125) -16 + j*(111) -16 + j*(-48) --190 + j*(-33) --182 + j*(265) -206 + j*(314) -344 + j*(-115) --71 + j*(-330) --330 + j*(21) --79 + j*(273) -98 + j*(139) -45 + j*(103) -168 + j*(148) -262 + j*(-77) -10 + j*(-212) --114 + j*(34) -141 + j*(115) -204 + j*(-159) --43 + j*(-242) --132 + j*(-90) --115 + j*(-62) --211 + j*(23) --103 + j*(257) -225 + j*(193) -228 + j*(-151) --64 + j*(-209) --135 + j*(-3) --9 + j*(37) --16 + j*(-38) --65 + j*(2) --9 + j*(28) --17 + j*(-59) --173 + j*(-44) --218 + j*(197) -60 + j*(376) -379 + j*(150) -269 + j*(-243) --109 + j*(-243) --162 + j*(63) -66 + j*(113) -81 + j*(-51) --37 + j*(-18) -35 + j*(69) -100 + j*(-15) -40 + j*(-34) -110 + j*(-2) -157 + j*(-185) --97 + j*(-291) --256 + j*(-37) --44 + j*(111) -45 + j*(-82) --172 + j*(-120) --209 + j*(113) --8 + j*(174) -56 + j*(55) -19 + j*(27) -41 + j*(8) --13 + j*(-49) --89 + j*(33) -17 + j*(125) -119 + j*(4) -6 + j*(-98) --88 + j*(-2) --11 + j*(70) -25 + j*(18) --7 + j*(28) -58 + j*(59) -112 + j*(-53) --15 + j*(-151) --150 + j*(-53) --114 + j*(76) --48 + j*(92) --37 + j*(117) -45 + j*(177) -184 + j*(117) -210 + j*(-41) -116 + j*(-142) -1 + j*(-157) --101 + j*(-91) --107 + j*(54) -39 + j*(117) -136 + j*(-5) -49 + j*(-109) --28 + j*(-47) -35 + j*(-3) -76 + j*(-88) --8 + j*(-164) --124 + j*(-138) --185 + j*(-31) --127 + j*(90) --1 + j*(72) --35 + j*(-47) --191 + j*(39) --83 + j*(275) -226 + j*(209) -233 + j*(-107) --24 + j*(-156) --54 + j*(23) -73 + j*(-1) -4 + j*(-107) --91 + j*(-16) -14 + j*(49) -49 + j*(-82) --109 + j*(-105) --136 + j*(57) -6 + j*(71) --23 + j*(-66) --205 + j*(0) --170 + j*(249) -99 + j*(314) -259 + j*(119) -187 + j*(-54) -83 + j*(-64) -80 + j*(-42) -74 + j*(-91) --12 + j*(-110) --60 + j*(-23) -15 + j*(33) -69 + j*(-41) --9 + j*(-100) --71 + j*(-27) --15 + j*(25) -7 + j*(-19) --36 + j*(-1) -28 + j*(59) -127 + j*(-49) --5 + j*(-206) --233 + j*(-87) --170 + j*(190) -111 + j*(216) -231 + j*(-8) -119 + j*(-180) --25 + j*(-201) --130 + j*(-160) --214 + j*(-70) --226 + j*(76) --125 + j*(190) -18 + j*(189) -89 + j*(100) -66 + j*(33) -50 + j*(39) -93 + j*(19) -85 + j*(-71) --31 + j*(-95) --86 + j*(21) -30 + j*(101) -147 + j*(-8) -78 + j*(-171) --108 + j*(-180) --200 + j*(-35) --151 + j*(91) --68 + j*(125) --8 + j*(127) -56 + j*(101) -77 + j*(23) -11 + j*(-21) --42 + j*(26) --31 + j*(79) --11 + j*(127) -71 + j*(201) -253 + j*(163) -330 + j*(-45) -214 + j*(-199) -112 + j*(-206) -83 + j*(-250) --57 + j*(-326) --268 + j*(-235) --325 + j*(4) --178 + j*(190) -42 + j*(175) -108 + j*(-13) --57 + j*(-97) --132 + j*(84) -90 + j*(159) -181 + j*(-96) --88 + j*(-200) --194 + j*(58) -47 + j*(148) -115 + j*(-77) --90 + j*(-131) --146 + j*(30) --64 + j*(77) --58 + j*(88) -11 + j*(163) -161 + j*(100) -155 + j*(-69) -41 + j*(-119) --9 + j*(-103) --74 + j*(-113) --176 + j*(-38) --165 + j*(134) -11 + j*(231) -211 + j*(119) -199 + j*(-142) --76 + j*(-228) --226 + j*(30) -9 + j*(209) -200 + j*(-6) -21 + j*(-205) --164 + j*(-93) --141 + j*(21) --167 + j*(45) --193 + j*(214) -25 + j*(373) -298 + j*(247) -339 + j*(-19) -193 + j*(-187) -6 + j*(-186) --74 + j*(-49) -9 + j*(35) -66 + j*(-16) -44 + j*(-30) -100 + j*(-42) -60 + j*(-196) --193 + j*(-154) --158 + j*(175) -229 + j*(144) -200 + j*(-293) --264 + j*(-284) --288 + j*(158) -83 + j*(194) -88 + j*(-88) --126 + j*(-33) --25 + j*(153) -156 + j*(48) -86 + j*(-111) --18 + j*(-86) --4 + j*(-40) -15 + j*(-69) --14 + j*(-108) --82 + j*(-122) --151 + j*(-66) --136 + j*(14) --91 + j*(25) --88 + j*(16) --79 + j*(6) --142 + j*(-51) --326 + j*(49) --298 + j*(388) -96 + j*(531) -383 + j*(238) -268 + j*(-56) -84 + j*(-71) -29 + j*(-13) -1 + j*(42) -54 + j*(143) -218 + j*(122) -266 + j*(-61) -140 + j*(-158) -66 + j*(-114) -79 + j*(-106) -57 + j*(-148) -2 + j*(-156) --47 + j*(-148) --113 + j*(-105) --115 + j*(8) -15 + j*(54) -98 + j*(-83) --35 + j*(-215) --214 + j*(-125) --200 + j*(57) --76 + j*(100) --28 + j*(53) --25 + j*(40) --6 + j*(14) --44 + j*(-23) --100 + j*(23) --60 + j*(91) --9 + j*(66) --38 + j*(46) --46 + j*(100) -6 + j*(135) -68 + j*(144) -162 + j*(107) -194 + j*(-35) -66 + j*(-109) -26 + j*(-7) -151 + j*(-57) -23 + j*(-262) --274 + j*(-100) --108 + j*(252) -257 + j*(83) -76 + j*(-270) --252 + j*(-71) --45 + j*(216) -184 + j*(10) --11 + j*(-144) --75 + j*(35) -95 + j*(13) -1 + j*(-161) --164 + j*(-30) --23 + j*(100) -51 + j*(-47) --111 + j*(-62) --88 + j*(113) -86 + j*(73) -46 + j*(-92) --112 + j*(-87) --181 + j*(48) --118 + j*(214) -111 + j*(260) -245 + j*(37) -64 + j*(-98) -10 + j*(86) -279 + j*(38) -194 + j*(-350) --269 + j*(-301) --269 + j*(151) -103 + j*(166) -97 + j*(-110) --85 + j*(-75) --29 + j*(7) --47 + j*(-75) --155 + j*(13) --47 + j*(115) --23 + j*(8) --161 + j*(115) -73 + j*(341) -402 + j*(43) -104 + j*(-348) --291 + j*(-73) --41 + j*(291) -286 + j*(80) -141 + j*(-188) --30 + j*(-125) --25 + j*(-79) --93 + j*(-71) --95 + j*(68) -67 + j*(79) -82 + j*(-76) --42 + j*(-91) --57 + j*(-19) --46 + j*(-17) --73 + j*(24) --16 + j*(76) -40 + j*(37) -27 + j*(22) -93 + j*(28) -146 + j*(-124) --43 + j*(-261) --264 + j*(-112) --212 + j*(122) --37 + j*(161) -26 + j*(78) -6 + j*(52) -33 + j*(64) -81 + j*(0) --1 + j*(-100) --160 + j*(-18) --111 + j*(191) -105 + j*(204) -164 + j*(69) -171 + j*(43) -288 + j*(-88) -132 + j*(-406) --337 + j*(-333) --398 + j*(167) -19 + j*(324) -200 + j*(46) -62 + j*(-95) --21 + j*(-85) --133 + j*(-71) --204 + j*(156) -99 + j*(325) -346 + j*(9) -52 + j*(-248) --148 + j*(45) -208 + j*(187) -358 + j*(-264) --139 + j*(-507) --506 + j*(-58) --180 + j*(391) -290 + j*(215) -249 + j*(-226) --124 + j*(-294) --255 + j*(-22) --95 + j*(107) --29 + j*(27) --74 + j*(37) --13 + j*(66) --13 + j*(-32) --161 + j*(-1) --132 + j*(199) -66 + j*(206) -91 + j*(81) -59 + j*(102) -163 + j*(83) -148 + j*(-71) -2 + j*(-67) -16 + j*(41) -86 + j*(13) -69 + j*(-12) -115 + j*(-17) -103 + j*(-153) --99 + j*(-158) --127 + j*(71) -85 + j*(114) -129 + j*(-27) -112 + j*(-34) -218 + j*(-152) -32 + j*(-427) --383 + j*(-278) --339 + j*(162) -15 + j*(195) -56 + j*(-23) --36 + j*(-38) --22 + j*(-61) --161 + j*(-107) --261 + j*(129) -12 + j*(298) -224 + j*(59) -70 + j*(-136) --52 + j*(-70) --47 + j*(-59) --140 + j*(-52) --154 + j*(98) --23 + j*(129) --24 + j*(57) --47 + j*(139) -116 + j*(153) -151 + j*(-49) --37 + j*(-100) --79 + j*(33) --25 + j*(25) --133 + j*(35) --129 + j*(269) -173 + j*(357) -363 + j*(115) -275 + j*(-83) -205 + j*(-116) -185 + j*(-214) -9 + j*(-309) --196 + j*(-190) --194 + j*(33) --32 + j*(125) -95 + j*(32) -40 + j*(-100) --120 + j*(-52) --76 + j*(165) -205 + j*(163) -271 + j*(-156) --33 + j*(-278) --160 + j*(-15) -83 + j*(70) -123 + j*(-186) --147 + j*(-210) --156 + j*(40) -52 + j*(11) --41 + j*(-169) --214 + j*(-28) --52 + j*(142) -107 + j*(-16) --21 + j*(-165) --147 + j*(-124) --230 + j*(-78) --342 + j*(105) --146 + j*(390) -249 + j*(259) -194 + j*(-158) --195 + j*(-152) --223 + j*(187) -37 + j*(253) -122 + j*(97) -56 + j*(23) --13 + j*(51) -5 + j*(165) -209 + j*(189) -316 + j*(-83) -35 + j*(-265) --167 + j*(-19) -47 + j*(158) -181 + j*(-25) -46 + j*(-106) -53 + j*(-27) -105 + j*(-142) --91 + j*(-211) --183 + j*(-4) --4 + j*(66) --1 + j*(-104) --207 + j*(-59) --187 + j*(189) -39 + j*(249) -162 + j*(117) -140 + j*(-4) -64 + j*(-35) -35 + j*(21) -118 + j*(47) -178 + j*(-62) -99 + j*(-157) -27 + j*(-137) -33 + j*(-146) --40 + j*(-216) --193 + j*(-161) --205 + j*(27) --36 + j*(80) -11 + j*(-88) --214 + j*(-137) --328 + j*(147) --54 + j*(356) -190 + j*(168) -86 + j*(-4) -30 + j*(81) -143 + j*(59) -93 + j*(-39) -91 + j*(59) -321 + j*(-57) -171 + j*(-471) --364 + j*(-392) --382 + j*(114) --21 + j*(144) --91 + j*(-66) --223 + j*(142) -67 + j*(259) -170 + j*(-28) --49 + j*(-78) --8 + j*(59) -57 + j*(-97) --209 + j*(-124) --242 + j*(199) -52 + j*(252) -82 + j*(60) -1 + j*(119) -163 + j*(142) -177 + j*(-79) --37 + j*(-81) --11 + j*(94) -128 + j*(43) -76 + j*(-49) -56 + j*(-5) -112 + j*(-57) -29 + j*(-132) --37 + j*(-64) -15 + j*(-53) --33 + j*(-123) --136 + j*(-69) --132 + j*(37) --85 + j*(86) --25 + j*(117) -38 + j*(82) -11 + j*(58) -51 + j*(136) -216 + j*(64) -161 + j*(-162) --64 + j*(-133) --36 + j*(40) -72 + j*(-15) --13 + j*(-60) -1 + j*(43) -103 + j*(-13) -25 + j*(-83) -36 + j*(16) -181 + j*(-104) --18 + j*(-312) --258 + j*(-88) --38 + j*(113) -69 + j*(-120) --192 + j*(-119) --91 + j*(164) -205 + j*(-31) --57 + j*(-346) --381 + j*(-87) --197 + j*(186) --54 + j*(93) --95 + j*(115) -54 + j*(133) -33 + j*(-93) --244 + j*(-11) --107 + j*(305) -207 + j*(138) -18 + j*(-119) --147 + j*(105) -119 + j*(175) -96 + j*(-133) --253 + j*(-41) --149 + j*(344) -222 + j*(285) -220 + j*(11) -82 + j*(6) -124 + j*(48) -144 + j*(-33) -71 + j*(-71) -6 + j*(-41) --13 + j*(59) -137 + j*(151) -328 + j*(-30) -182 + j*(-309) --106 + j*(-240) --87 + j*(-27) -31 + j*(-71) --78 + j*(-133) --141 + j*(31) -40 + j*(122) -172 + j*(-39) -65 + j*(-214) --133 + j*(-192) --195 + j*(-4) --39 + j*(106) -78 + j*(-33) --74 + j*(-144) --187 + j*(40) -24 + j*(165) -167 + j*(-59) --47 + j*(-227) --223 + j*(-54) --111 + j*(86) --56 + j*(2) --182 + j*(34) --129 + j*(248) -155 + j*(257) -254 + j*(-10) -76 + j*(-153) --18 + j*(-66) -47 + j*(-84) --64 + j*(-223) --321 + j*(-112) --313 + j*(218) --22 + j*(334) -153 + j*(167) -99 + j*(27) -22 + j*(46) -63 + j*(111) -179 + j*(66) -187 + j*(-107) -5 + j*(-195) --132 + j*(-49) --30 + j*(89) -84 + j*(16) -40 + j*(-76) --21 + j*(-76) --74 + j*(-69) --136 + j*(7) --70 + j*(119) -35 + j*(62) --59 + j*(2) --95 + j*(186) -182 + j*(254) -316 + j*(-60) -25 + j*(-243) --161 + j*(4) -49 + j*(172) -197 + j*(2) -77 + j*(-119) -9 + j*(-37) -89 + j*(-21) -93 + j*(-126) --8 + j*(-157) --58 + j*(-104) --63 + j*(-88) --116 + j*(-65) --126 + j*(49) -14 + j*(114) -130 + j*(-16) -37 + j*(-168) --119 + j*(-136) --157 + j*(-20) --112 + j*(59) --28 + j*(83) -31 + j*(3) --67 + j*(-66) --148 + j*(71) -28 + j*(179) -158 + j*(-12) --24 + j*(-141) --117 + j*(20) -31 + j*(50) --12 + j*(-100) --171 + j*(-1) --35 + j*(156) -93 + j*(-4) --98 + j*(-98) --174 + j*(116) -35 + j*(187) -96 + j*(18) --18 + j*(-19) --39 + j*(40) --48 + j*(51) --66 + j*(136) -66 + j*(216) -198 + j*(115) -176 + j*(-5) -137 + j*(-35) -116 + j*(-69) -88 + j*(-67) -142 + j*(-100) -82 + j*(-290) --246 + j*(-293) --373 + j*(76) --87 + j*(290) -103 + j*(158) -93 + j*(109) -226 + j*(86) -247 + j*(-175) --47 + j*(-240) --90 + j*(38) -199 + j*(8) -119 + j*(-333) --255 + j*(-281) --264 + j*(42) --71 + j*(64) --111 + j*(-4) --120 + j*(132) -69 + j*(139) -86 + j*(-52) --85 + j*(-52) --62 + j*(112) -108 + j*(74) -86 + j*(-99) --75 + j*(-96) --78 + j*(42) -48 + j*(34) -23 + j*(-105) --137 + j*(-85) --141 + j*(82) --5 + j*(100) --5 + j*(16) --49 + j*(69) -77 + j*(88) -92 + j*(-113) --182 + j*(-150) --276 + j*(168) -23 + j*(330) -208 + j*(107) -64 + j*(-23) -19 + j*(103) -180 + j*(107) -218 + j*(-68) -98 + j*(-160) -4 + j*(-145) --81 + j*(-99) --108 + j*(50) -88 + j*(154) -288 + j*(-64) -101 + j*(-367) --256 + j*(-279) --276 + j*(37) --73 + j*(96) --68 + j*(-6) --135 + j*(78) -10 + j*(161) -100 + j*(9) --40 + j*(-54) --47 + j*(86) -120 + j*(31) -17 + j*(-182) --261 + j*(-69) --202 + j*(252) -85 + j*(308) -233 + j*(171) -313 + j*(39) -313 + j*(-197) -59 + j*(-351) --148 + j*(-180) --38 + j*(-49) --81 + j*(-46) --16 + j*(85) -103 + j*(-8) --16 + j*(-98) --54 + j*(54) -149 + j*(39) -102 + j*(-221) --192 + j*(-181) --167 + j*(105) -78 + j*(81) -42 + j*(-127) --145 + j*(-88) --132 + j*(79) -8 + j*(108) -81 + j*(4) -7 + j*(-110) --141 + j*(-67) --123 + j*(97) -32 + j*(84) --13 + j*(-54) --156 + j*(39) --35 + j*(213) -158 + j*(103) -86 + j*(-72) --36 + j*(-31) --8 + j*(33) -12 + j*(3) --18 + j*(3) --26 + j*(21) --40 + j*(49) --1 + j*(110) -91 + j*(77) -57 + j*(-6) -1 + j*(72) -150 + j*(144) -295 + j*(-41) -176 + j*(-265) --59 + j*(-291) --229 + j*(-135) --201 + j*(130) -114 + j*(213) -281 + j*(-125) --55 + j*(-348) --282 + j*(-45) --9 + j*(112) -31 + j*(-186) --354 + j*(-137) --294 + j*(325) -173 + j*(303) -168 + j*(-91) --138 + j*(-62) --81 + j*(177) -95 + j*(133) -79 + j*(59) -144 + j*(83) -242 + j*(-95) -37 + j*(-299) --247 + j*(-161) --223 + j*(132) -5 + j*(216) -146 + j*(88) -110 + j*(-48) -15 + j*(-57) -13 + j*(1) -62 + j*(-21) -42 + j*(-80) --10 + j*(-93) --57 + j*(-95) --132 + j*(-48) --117 + j*(71) --4 + j*(81) --21 + j*(-1) --98 + j*(76) -10 + j*(199) -175 + j*(142) -238 + j*(12) -245 + j*(-152) -62 + j*(-344) --260 + j*(-221) --199 + j*(131) -117 + j*(80) -23 + j*(-192) --208 + j*(-39) --1 + j*(132) -88 + j*(-134) --250 + j*(-153) --228 + j*(236) -160 + j*(183) -52 + j*(-163) --254 + j*(30) -9 + j*(329) -326 + j*(51) -100 + j*(-272) --187 + j*(-156) --197 + j*(35) --144 + j*(139) --6 + j*(221) -158 + j*(98) -41 + j*(-88) --153 + j*(50) --9 + j*(281) -256 + j*(204) -310 + j*(-22) -224 + j*(-184) -53 + j*(-279) --167 + j*(-194) --196 + j*(51) --12 + j*(165) -132 + j*(88) -176 + j*(-17) -170 + j*(-149) -28 + j*(-263) --156 + j*(-184) --144 + j*(-11) --22 + j*(-8) --47 + j*(-112) --171 + j*(-77) --164 + j*(60) --51 + j*(81) --47 + j*(-8) --152 + j*(21) --140 + j*(176) -28 + j*(229) -139 + j*(130) -151 + j*(42) -165 + j*(-37) -103 + j*(-161) --70 + j*(-179) --158 + j*(-38) --97 + j*(66) --30 + j*(76) -13 + j*(75) -59 + j*(37) -47 + j*(-21) -20 + j*(-23) -34 + j*(-53) --50 + j*(-124) --206 + j*(-18) --139 + j*(218) -118 + j*(235) -202 + j*(41) -112 + j*(-37) -115 + j*(-7) -166 + j*(-97) -58 + j*(-223) --95 + j*(-175) --90 + j*(-58) --28 + j*(-78) --98 + j*(-123) --185 + j*(-47) --167 + j*(49) --157 + j*(98) --117 + j*(235) -140 + j*(299) -325 + j*(19) -93 + j*(-212) --86 + j*(-13) -160 + j*(75) -199 + j*(-272) --233 + j*(-331) --342 + j*(107) -18 + j*(229) -87 + j*(-29) --98 + j*(6) -40 + j*(168) -213 + j*(-25) -25 + j*(-207) --131 + j*(-75) --62 + j*(12) --69 + j*(-28) --123 + j*(47) --41 + j*(129) -35 + j*(94) -56 + j*(64) -83 + j*(13) -10 + j*(-50) --74 + j*(51) -56 + j*(165) -204 + j*(49) -142 + j*(-91) -78 + j*(-69) -125 + j*(-101) -64 + j*(-228) --124 + j*(-233) --235 + j*(-74) --181 + j*(107) --5 + j*(154) -80 + j*(28) --16 + j*(-20) -17 + j*(107) -236 + j*(8) -134 + j*(-330) --291 + j*(-291) --337 + j*(137) -24 + j*(231) -107 + j*(-56) --137 + j*(-117) --220 + j*(99) --74 + j*(236) -87 + j*(215) -190 + j*(102) -170 + j*(-55) -44 + j*(-113) --37 + j*(-57) --55 + j*(-3) --64 + j*(71) -32 + j*(159) -192 + j*(98) -202 + j*(-74) -95 + j*(-137) -58 + j*(-116) -57 + j*(-165) --45 + j*(-228) --190 + j*(-177) --257 + j*(-37) --233 + j*(117) --110 + j*(246) -111 + j*(260) -280 + j*(59) -185 + j*(-203) --71 + j*(-223) --153 + j*(-43) --52 + j*(22) --49 + j*(-45) --122 + j*(-13) --112 + j*(59) --109 + j*(77) --118 + j*(186) -57 + j*(296) -267 + j*(158) -236 + j*(-60) -112 + j*(-116) -49 + j*(-120) --46 + j*(-100) --64 + j*(30) -73 + j*(61) -98 + j*(-70) --2 + j*(-81) -14 + j*(-40) --16 + j*(-98) --130 + j*(4) -43 + j*(180) -282 + j*(-47) -43 + j*(-334) --238 + j*(-124) --54 + j*(81) -45 + j*(-129) --231 + j*(-156) --253 + j*(165) -40 + j*(216) -103 + j*(1) --19 + j*(-45) --43 + j*(-1) --65 + j*(13) --57 + j*(88) -45 + j*(73) -1 + j*(-36) --126 + j*(59) --6 + j*(226) -196 + j*(142) -196 + j*(-37) -100 + j*(-117) --24 + j*(-124) --115 + j*(30) -78 + j*(194) -328 + j*(-31) -119 + j*(-364) --248 + j*(-228) --198 + j*(104) -54 + j*(115) -112 + j*(-59) -21 + j*(-175) --156 + j*(-185) --276 + j*(3) --127 + j*(174) --3 + j*(57) --167 + j*(33) --131 + j*(307) -233 + j*(283) -233 + j*(-86) --93 + j*(-55) -10 + j*(262) -358 + j*(125) -259 + j*(-226) --8 + j*(-181) -48 + j*(-40) -110 + j*(-176) --99 + j*(-247) --218 + j*(-33) --54 + j*(109) -65 + j*(-14) --57 + j*(-100) --139 + j*(45) -28 + j*(158) -182 + j*(0) -69 + j*(-180) --88 + j*(-124) --69 + j*(-43) --74 + j*(-78) --165 + j*(-21) --103 + j*(114) -45 + j*(63) --7 + j*(-81) --170 + j*(-40) --177 + j*(142) --13 + j*(234) -148 + j*(132) -103 + j*(-50) --79 + j*(-21) --26 + j*(179) -214 + j*(95) -111 + j*(-183) --202 + j*(-62) --65 + j*(286) -315 + j*(166) -247 + j*(-214) --81 + j*(-214) --130 + j*(21) -3 + j*(99) -97 + j*(65) -159 + j*(-36) -64 + j*(-176) --128 + j*(-100) --64 + j*(124) -179 + j*(76) -174 + j*(-169) --23 + j*(-226) --122 + j*(-134) --151 + j*(-48) --122 + j*(69) -34 + j*(99) -103 + j*(-63) --43 + j*(-161) --153 + j*(-62) --126 + j*(22) --119 + j*(59) --62 + j*(153) -116 + j*(122) -127 + j*(-105) --116 + j*(-155) --199 + j*(83) -21 + j*(189) -140 + j*(-9) --33 + j*(-146) --199 + j*(-18) --157 + j*(160) --21 + j*(222) -100 + j*(185) -158 + j*(81) -110 + j*(-5) -48 + j*(25) -108 + j*(71) -187 + j*(-6) -154 + j*(-117) -86 + j*(-159) -15 + j*(-206) --144 + j*(-207) --269 + j*(-13) --130 + j*(208) -117 + j*(156) -132 + j*(-68) --62 + j*(-125) --164 + j*(41) --47 + j*(194) -119 + j*(163) -163 + j*(57) -165 + j*(20) -226 + j*(-57) -159 + j*(-233) --67 + j*(-223) --69 + j*(-4) -162 + j*(-57) -66 + j*(-364) --327 + j*(-300) --351 + j*(98) --35 + j*(180) -35 + j*(-36) --113 + j*(-70) --138 + j*(25) --122 + j*(54) --122 + j*(134) -18 + j*(202) -151 + j*(71) -77 + j*(-88) --50 + j*(-88) --115 + j*(-35) --170 + j*(60) --103 + j*(218) -100 + j*(221) -163 + j*(52) -70 + j*(0) -94 + j*(52) -177 + j*(-44) -76 + j*(-206) --129 + j*(-180) --207 + j*(-13) --145 + j*(124) --36 + j*(175) -72 + j*(143) -110 + j*(42) -35 + j*(-27) --54 + j*(42) -8 + j*(174) -184 + j*(151) -238 + j*(-20) -127 + j*(-120) -41 + j*(-89) -18 + j*(-49) -14 + j*(13) -120 + j*(69) -255 + j*(-63) -156 + j*(-270) --48 + j*(-243) --50 + j*(-122) --13 + j*(-175) --153 + j*(-200) --223 + j*(-23) --74 + j*(87) -52 + j*(-10) -15 + j*(-144) --121 + j*(-197) --276 + j*(-108) --284 + j*(95) --121 + j*(185) --32 + j*(103) --72 + j*(75) --62 + j*(121) --23 + j*(132) -16 + j*(161) -151 + j*(142) -204 + j*(-68) --15 + j*(-202) --190 + j*(-33) --98 + j*(127) --8 + j*(94) --21 + j*(100) -47 + j*(135) -111 + j*(59) -66 + j*(-3) -42 + j*(13) -32 + j*(-7) --28 + j*(33) -42 + j*(144) -214 + j*(71) -183 + j*(-139) --11 + j*(-169) --77 + j*(-37) --13 + j*(28) -28 + j*(4) -6 + j*(-13) --9 + j*(39) -87 + j*(86) -190 + j*(-39) -71 + j*(-185) --72 + j*(-78) -59 + j*(27) -148 + j*(-169) --95 + j*(-299) --284 + j*(-90) --183 + j*(114) --41 + j*(128) -42 + j*(76) -41 + j*(-37) --104 + j*(-27) --61 + j*(190) -254 + j*(127) -204 + j*(-261) --199 + j*(-235) --174 + j*(119) -93 + j*(52) --48 + j*(-120) --139 + j*(107) -165 + j*(136) -159 + j*(-217) --197 + j*(-197) --162 + j*(107) -62 + j*(37) --49 + j*(-124) --175 + j*(-10) --124 + j*(65) --156 + j*(110) --60 + j*(294) -245 + j*(221) -237 + j*(-116) --35 + j*(-135) --19 + j*(35) -81 + j*(-70) --105 + j*(-158) --230 + j*(45) --98 + j*(192) -4 + j*(180) -74 + j*(200) -221 + j*(139) -243 + j*(-57) -95 + j*(-151) --8 + j*(-93) --18 + j*(-30) -0 + j*(6) -32 + j*(16) -68 + j*(11) -120 + j*(-41) -82 + j*(-187) --162 + j*(-208) --276 + j*(105) -57 + j*(322) -353 + j*(23) -128 + j*(-309) --186 + j*(-168) --115 + j*(102) -116 + j*(84) -170 + j*(-120) -5 + j*(-276) --236 + j*(-190) --244 + j*(74) --15 + j*(129) -18 + j*(-59) --169 + j*(-57) --166 + j*(146) -8 + j*(187) -89 + j*(97) -104 + j*(8) -26 + j*(-96) --151 + j*(-27) --93 + j*(222) -204 + j*(211) -271 + j*(-60) -118 + j*(-177) -35 + j*(-197) --118 + j*(-234) --296 + j*(-45) --152 + j*(199) -51 + j*(112) --34 + j*(23) --15 + j*(175) -233 + j*(110) -190 + j*(-203) --110 + j*(-227) --203 + j*(-18) --148 + j*(100) --77 + j*(214) -154 + j*(251) -313 + j*(-6) -112 + j*(-228) --91 + j*(-103) -2 + j*(36) -103 + j*(-71) --13 + j*(-194) --187 + j*(-126) --211 + j*(74) --35 + j*(177) -103 + j*(34) --38 + j*(-107) --194 + j*(48) --54 + j*(236) -139 + j*(153) -111 + j*(17) -49 + j*(28) -78 + j*(55) -118 + j*(41) -170 + j*(-4) -170 + j*(-122) -45 + j*(-183) --30 + j*(-103) -19 + j*(-76) --4 + j*(-136) --82 + j*(-109) --69 + j*(-55) --71 + j*(-72) --119 + j*(-47) --114 + j*(8) --107 + j*(29) --91 + j*(101) -47 + j*(107) -65 + j*(-80) --173 + j*(-102) --209 + j*(184) -93 + j*(252) -185 + j*(-21) --38 + j*(-115) --121 + j*(50) --29 + j*(117) --6 + j*(107) -30 + j*(156) -132 + j*(152) -189 + j*(82) -221 + j*(23) -244 + j*(-66) -218 + j*(-163) -179 + j*(-264) -26 + j*(-409) --295 + j*(-341) --363 + j*(37) --18 + j*(168) -91 + j*(-151) --255 + j*(-233) --349 + j*(125) --42 + j*(233) -11 + j*(0) --204 + j*(31) --136 + j*(288) -141 + j*(272) -200 + j*(45) -67 + j*(-45) --9 + j*(32) -59 + j*(119) -215 + j*(54) -209 + j*(-194) --94 + j*(-302) --320 + j*(-16) --112 + j*(284) -194 + j*(171) -148 + j*(-88) --57 + j*(-61) --19 + j*(124) -183 + j*(101) -230 + j*(-124) -29 + j*(-272) --207 + j*(-153) --192 + j*(122) -68 + j*(192) -184 + j*(-30) -1 + j*(-141) --74 + j*(33) -127 + j*(67) -157 + j*(-180) --114 + j*(-251) --228 + j*(-17) --82 + j*(104) --14 + j*(49) --8 + j*(66) -86 + j*(42) -71 + j*(-99) --79 + j*(-98) --80 + j*(25) --6 + j*(4) --71 + j*(-25) --71 + j*(88) -77 + j*(71) -49 + j*(-103) --151 + j*(-70) --147 + j*(149) -59 + j*(213) -199 + j*(84) -207 + j*(-97) -67 + j*(-251) --182 + j*(-228) --293 + j*(14) --147 + j*(204) -23 + j*(180) -74 + j*(98) -80 + j*(47) -62 + j*(-4) -2 + j*(-7) --12 + j*(57) -57 + j*(87) -107 + j*(38) -102 + j*(0) -119 + j*(-10) -156 + j*(-88) -71 + j*(-206) --96 + j*(-164) --83 + j*(-8) -54 + j*(-48) --49 + j*(-215) --287 + j*(-91) --204 + j*(205) -94 + j*(183) -115 + j*(-76) --100 + j*(-132) --210 + j*(28) --159 + j*(198) -22 + j*(296) -242 + j*(185) -238 + j*(-55) -69 + j*(-94) -85 + j*(-11) -148 + j*(-138) --55 + j*(-249) --222 + j*(-41) --63 + j*(134) -74 + j*(28) -4 + j*(-62) --53 + j*(-33) --95 + j*(4) --113 + j*(147) -127 + j*(271) -388 + j*(-3) -170 + j*(-368) --207 + j*(-255) --165 + j*(28) --20 + j*(-34) --176 + j*(-87) --212 + j*(161) -56 + j*(214) -88 + j*(-25) --130 + j*(20) --13 + j*(269) -270 + j*(145) -179 + j*(-109) -32 + j*(-13) -214 + j*(32) -240 + j*(-249) --54 + j*(-318) --115 + j*(-124) --49 + j*(-179) --281 + j*(-192) --308 + j*(177) -122 + j*(210) -110 + j*(-257) --413 + j*(-193) --341 + j*(371) -194 + j*(319) -129 + j*(-114) --196 + j*(16) -9 + j*(273) -226 + j*(30) --14 + j*(-144) --143 + j*(71) -37 + j*(160) -98 + j*(29) -11 + j*(-23) --62 + j*(30) --59 + j*(172) -170 + j*(260) -374 + j*(-22) -91 + j*(-315) --235 + j*(-52) -17 + j*(264) -308 + j*(32) -112 + j*(-209) --40 + j*(-46) -129 + j*(11) -146 + j*(-182) --29 + j*(-237) --134 + j*(-165) --228 + j*(-64) --201 + j*(183) -124 + j*(269) -307 + j*(-57) -36 + j*(-274) --158 + j*(-65) -25 + j*(76) -141 + j*(-103) --4 + j*(-233) --125 + j*(-177) --166 + j*(-139) --263 + j*(-87) --305 + j*(98) --144 + j*(253) -52 + j*(184) -46 + j*(33) --37 + j*(44) -24 + j*(87) -57 + j*(-37) --132 + j*(-75) --199 + j*(168) -64 + j*(276) -189 + j*(35) --25 + j*(-61) --81 + j*(156) -144 + j*(209) -223 + j*(22) -127 + j*(-48) -130 + j*(-33) -136 + j*(-127) -8 + j*(-185) --102 + j*(-104) --106 + j*(10) --30 + j*(91) -103 + j*(66) -124 + j*(-93) --32 + j*(-141) --78 + j*(-13) -25 + j*(-13) --52 + j*(-115) --190 + j*(29) --10 + j*(219) -214 + j*(38) -43 + j*(-186) --152 + j*(-14) -47 + j*(155) -214 + j*(-83) --40 + j*(-281) --275 + j*(-59) --132 + j*(180) -62 + j*(122) -66 + j*(18) -66 + j*(-15) -33 + j*(-124) --178 + j*(-131) --274 + j*(151) -3 + j*(363) -296 + j*(180) -255 + j*(-107) -62 + j*(-172) --33 + j*(-97) --42 + j*(-28) --8 + j*(23) -67 + j*(13) -92 + j*(-84) --1 + j*(-163) --136 + j*(-114) --154 + j*(33) --37 + j*(105) -46 + j*(37) -23 + j*(-28) --10 + j*(-42) --65 + j*(-58) --161 + j*(40) --48 + j*(238) -242 + j*(153) -208 + j*(-176) --96 + j*(-171) --71 + j*(79) -141 + j*(0) -22 + j*(-195) --145 + j*(-69) --23 + j*(32) -1 + j*(-106) --158 + j*(-91) --144 + j*(37) --114 + j*(6) --225 + j*(88) --99 + j*(313) -187 + j*(224) -156 + j*(-27) -6 + j*(-21) -26 + j*(18) --44 + j*(-21) --110 + j*(156) -166 + j*(279) -373 + j*(-39) -102 + j*(-322) --210 + j*(-171) --206 + j*(98) --38 + j*(230) -175 + j*(190) -238 + j*(-39) -24 + j*(-137) --42 + j*(72) -193 + j*(92) -178 + j*(-170) --78 + j*(-119) -30 + j*(127) -289 + j*(-23) -171 + j*(-293) --29 + j*(-264) --54 + j*(-238) --212 + j*(-272) --380 + j*(-33) --190 + j*(227) -57 + j*(135) -23 + j*(-16) --23 + j*(14) -38 + j*(-11) --19 + j*(-117) --170 + j*(-73) --187 + j*(109) --20 + j*(211) -161 + j*(103) -127 + j*(-109) --69 + j*(-141) --123 + j*(8) --30 + j*(41) --50 + j*(-23) --117 + j*(51) --20 + j*(134) -69 + j*(46) --4 + j*(-28) --60 + j*(30) --26 + j*(81) -18 + j*(88) -84 + j*(67) -106 + j*(-46) --32 + j*(-121) --155 + j*(11) --52 + j*(162) -104 + j*(91) -49 + j*(-57) --107 + j*(-10) --84 + j*(162) -78 + j*(184) -108 + j*(79) -66 + j*(119) -233 + j*(180) -402 + j*(-80) -151 + j*(-373) --197 + j*(-202) --103 + j*(110) -122 + j*(50) -57 + j*(-78) -13 + j*(30) -183 + j*(25) -190 + j*(-180) -16 + j*(-221) --12 + j*(-131) -28 + j*(-171) --58 + j*(-234) --159 + j*(-191) --208 + j*(-126) --233 + j*(-35) --175 + j*(46) --124 + j*(7) --218 + j*(2) --249 + j*(175) --74 + j*(280) -54 + j*(189) -38 + j*(134) -87 + j*(160) -177 + j*(76) -134 + j*(-44) -55 + j*(-45) -66 + j*(-36) -42 + j*(-107) --86 + j*(-110) --147 + j*(40) --18 + j*(158) -138 + j*(78) -116 + j*(-87) --26 + j*(-118) --91 + j*(-23) --45 + j*(52) -23 + j*(49) -59 + j*(-13) -6 + j*(-88) --102 + j*(-58) --103 + j*(64) -0 + j*(80) -0 + j*(1) --79 + j*(38) --22 + j*(141) -101 + j*(96) -76 + j*(-18) --18 + j*(6) -22 + j*(97) -136 + j*(53) -112 + j*(-92) --50 + j*(-98) --86 + j*(70) -83 + j*(131) -158 + j*(-28) -12 + j*(-99) --45 + j*(52) -128 + j*(119) -250 + j*(-48) -161 + j*(-238) --41 + j*(-281) --210 + j*(-143) --170 + j*(83) -44 + j*(117) -103 + j*(-55) --17 + j*(-90) -6 + j*(-11) -67 + j*(-115) --100 + j*(-185) --186 + j*(7) -6 + j*(85) -59 + j*(-106) --128 + j*(-150) --174 + j*(-2) --106 + j*(23) --146 + j*(30) --115 + j*(137) -16 + j*(115) --12 + j*(10) --88 + j*(73) -11 + j*(140) -76 + j*(25) --41 + j*(-23) --69 + j*(100) -61 + j*(120) -73 + j*(-14) --76 + j*(-17) --76 + j*(166) -146 + j*(190) -203 + j*(-59) --65 + j*(-141) --179 + j*(158) -127 + j*(331) -366 + j*(92) -271 + j*(-130) -192 + j*(-168) -129 + j*(-303) --170 + j*(-330) --313 + j*(18) -4 + j*(231) -230 + j*(-30) -35 + j*(-240) --133 + j*(-135) --115 + j*(-52) --153 + j*(-35) --172 + j*(101) --16 + j*(192) -129 + j*(86) -98 + j*(-69) --40 + j*(-105) --125 + j*(18) --9 + j*(138) -136 + j*(25) -25 + j*(-136) --140 + j*(-26) --40 + j*(128) -86 + j*(42) -8 + j*(-37) --24 + j*(43) -59 + j*(53) -67 + j*(-8) -61 + j*(-6) -91 + j*(-59) -16 + j*(-127) --57 + j*(-59) -2 + j*(-24) --6 + j*(-105) --116 + j*(-82) --112 + j*(23) --62 + j*(28) --76 + j*(44) --19 + j*(91) -38 + j*(19) --56 + j*(-11) --56 + j*(129) -135 + j*(124) -157 + j*(-80) -3 + j*(-127) --21 + j*(-65) --49 + j*(-135) --255 + j*(-85) --267 + j*(240) -88 + j*(366) -314 + j*(74) -134 + j*(-172) --48 + j*(-84) -16 + j*(-5) -13 + j*(-124) --199 + j*(-104) --243 + j*(177) -21 + j*(323) -231 + j*(174) -241 + j*(6) -211 + j*(-120) -67 + j*(-256) --177 + j*(-171) --163 + j*(88) -32 + j*(101) -6 + j*(3) --6 + j*(133) -254 + j*(110) -267 + j*(-250) --100 + j*(-334) --221 + j*(-70) --113 + j*(-4) --188 + j*(12) --129 + j*(237) -175 + j*(192) -129 + j*(-105) --121 + j*(4) -83 + j*(243) -358 + j*(-13) -136 + j*(-320) --134 + j*(-193) --85 + j*(-28) --25 + j*(-49) --39 + j*(-59) --42 + j*(-81) --126 + j*(-83) --144 + j*(44) --16 + j*(53) --59 + j*(-66) --182 + j*(48) --15 + j*(173) -83 + j*(-40) --190 + j*(-96) --234 + j*(235) -103 + j*(293) -141 + j*(22) --61 + j*(75) -105 + j*(276) -367 + j*(68) -211 + j*(-231) --35 + j*(-161) -0 + j*(-14) -74 + j*(-76) --12 + j*(-136) --82 + j*(-64) --36 + j*(-12) --21 + j*(-69) --129 + j*(-76) --170 + j*(76) --22 + j*(163) -64 + j*(42) --47 + j*(8) --32 + j*(148) -131 + j*(115) -85 + j*(-23) -4 + j*(89) -236 + j*(157) -371 + j*(-161) -77 + j*(-395) --167 + j*(-233) --142 + j*(-103) --190 + j*(-85) --221 + j*(99) --4 + j*(197) -113 + j*(18) --13 + j*(-54) --8 + j*(36) -69 + j*(-48) --64 + j*(-131) --150 + j*(8) --42 + j*(59) --83 + j*(-22) --187 + j*(132) -33 + j*(313) -291 + j*(114) -173 + j*(-157) --25 + j*(-118) --11 + j*(-26) --4 + j*(-68) --82 + j*(-47) --72 + j*(32) --42 + j*(31) --70 + j*(67) -2 + j*(145) -115 + j*(83) -69 + j*(-19) -2 + j*(51) -117 + j*(122) -245 + j*(2) -214 + j*(-159) -125 + j*(-253) --7 + j*(-340) --247 + j*(-320) --415 + j*(-74) --314 + j*(210) --62 + j*(283) -95 + j*(155) -68 + j*(13) --33 + j*(16) --16 + j*(117) -112 + j*(99) -112 + j*(-35) -4 + j*(-37) -42 + j*(50) -138 + j*(-35) -48 + j*(-168) --95 + j*(-132) --135 + j*(-46) --175 + j*(45) --99 + j*(234) -212 + j*(230) -308 + j*(-136) --42 + j*(-317) --255 + j*(-39) --71 + j*(141) -24 + j*(26) --61 + j*(32) -14 + j*(115) -88 + j*(12) --23 + j*(-21) -12 + j*(112) -178 + j*(14) -47 + j*(-193) --189 + j*(-53) --62 + j*(185) -148 + j*(84) -74 + j*(-69) --12 + j*(-4) -55 + j*(35) -66 + j*(-12) -81 + j*(13) -192 + j*(-59) -122 + j*(-283) --159 + j*(-285) --238 + j*(-45) --95 + j*(30) --93 + j*(-46) --166 + j*(18) --97 + j*(98) --63 + j*(34) --175 + j*(78) --115 + j*(289) -161 + j*(317) -301 + j*(96) -231 + j*(-69) -163 + j*(-127) -91 + j*(-209) --72 + j*(-214) --153 + j*(-78) --91 + j*(0) --83 + j*(-28) --144 + j*(37) --59 + j*(159) -102 + j*(96) -62 + j*(-69) --101 + j*(-29) --47 + j*(142) -145 + j*(75) -66 + j*(-145) --194 + j*(-59) --121 + j*(255) -226 + j*(237) -284 + j*(-82) -60 + j*(-177) -6 + j*(-68) -46 + j*(-112) --89 + j*(-147) --141 + j*(33) -42 + j*(86) -74 + j*(-95) --98 + j*(-101) --79 + j*(47) -28 + j*(-16) --104 + j*(-104) --210 + j*(83) --21 + j*(232) -139 + j*(103) -92 + j*(-8) -67 + j*(-16) -40 + j*(-74) --71 + j*(-34) -2 + j*(122) -231 + j*(6) -110 + j*(-317) --290 + j*(-269) --358 + j*(111) --109 + j*(267) -21 + j*(192) -65 + j*(185) -185 + j*(136) -192 + j*(-16) -103 + j*(-41) -150 + j*(-35) -134 + j*(-185) --76 + j*(-198) --94 + j*(1) -70 + j*(-44) --75 + j*(-212) --285 + j*(13) --35 + j*(257) -196 + j*(19) --34 + j*(-148) --113 + j*(96) -163 + j*(103) -129 + j*(-198) --148 + j*(-154) --99 + j*(44) --8 + j*(-47) --171 + j*(-51) --137 + j*(169) -82 + j*(134) -39 + j*(-27) --40 + j*(47) -66 + j*(49) -6 + j*(-69) --103 + j*(54) -69 + j*(132) -98 + j*(-70) --124 + j*(-29) --10 + j*(222) -260 + j*(67) -114 + j*(-181) --49 + j*(-58) -71 + j*(-25) --18 + j*(-165) --169 + j*(13) -81 + j*(142) -180 + j*(-171) --167 + j*(-261) --250 + j*(37) --76 + j*(62) --204 + j*(18) --202 + j*(334) -235 + j*(380) -347 + j*(-47) -23 + j*(-152) -3 + j*(66) -168 + j*(-11) -37 + j*(-153) --72 + j*(-21) -45 + j*(47) -83 + j*(-41) -49 + j*(-69) -35 + j*(-114) --78 + j*(-126) --99 + j*(24) -77 + j*(13) -19 + j*(-216) --276 + j*(-156) --284 + j*(150) --77 + j*(244) -25 + j*(216) -167 + j*(210) -296 + j*(-6) -105 + j*(-216) --93 + j*(-66) -57 + j*(64) -146 + j*(-127) --79 + j*(-224) --211 + j*(-19) --73 + j*(138) -80 + j*(81) -96 + j*(-46) -1 + j*(-110) --70 + j*(-42) -5 + j*(-4) -1 + j*(-139) --228 + j*(-139) --295 + j*(160) --11 + j*(317) -194 + j*(139) -155 + j*(-28) -108 + j*(-105) --11 + j*(-213) --255 + j*(-135) --271 + j*(165) --18 + j*(264) -84 + j*(119) -25 + j*(99) -105 + j*(161) -235 + j*(39) -151 + j*(-148) --40 + j*(-140) --90 + j*(16) -25 + j*(94) -120 + j*(14) -75 + j*(-83) -5 + j*(-74) -2 + j*(-60) --56 + j*(-86) --141 + j*(25) --11 + j*(178) -184 + j*(57) -73 + j*(-150) --120 + j*(-24) -37 + j*(170) -266 + j*(-8) -126 + j*(-279) --144 + j*(-231) --191 + j*(-41) --134 + j*(50) --66 + j*(119) -76 + j*(112) -122 + j*(-46) --18 + j*(-110) --66 + j*(10) -49 + j*(23) -34 + j*(-105) --104 + j*(-74) --68 + j*(72) -86 + j*(34) -71 + j*(-132) --91 + j*(-177) --204 + j*(-71) --194 + j*(69) --88 + j*(142) -6 + j*(93) --11 + j*(27) --46 + j*(41) --32 + j*(51) --63 + j*(48) --66 + j*(142) -88 + j*(167) -131 + j*(-28) --103 + j*(-74) --167 + j*(211) -144 + j*(334) -329 + j*(72) -173 + j*(-104) -86 + j*(-20) -187 + j*(-28) -176 + j*(-183) -21 + j*(-251) --116 + j*(-192) --187 + j*(-69) --146 + j*(75) --13 + j*(116) -58 + j*(46) -50 + j*(-4) -40 + j*(-40) --24 + j*(-63) --74 + j*(33) -59 + j*(116) -192 + j*(-36) -55 + j*(-223) --163 + j*(-145) --164 + j*(65) --1 + j*(142) -137 + j*(43) -119 + j*(-133) --65 + j*(-199) --193 + j*(-47) --95 + j*(98) -14 + j*(49) --11 + j*(-2) --1 + j*(20) -31 + j*(-43) --79 + j*(-95) --156 + j*(33) --37 + j*(119) -28 + j*(18) --74 + j*(-13) --95 + j*(91) --21 + j*(122) --11 + j*(119) -47 + j*(191) -222 + j*(151) -265 + j*(-71) -82 + j*(-185) --40 + j*(-66) -66 + j*(24) -174 + j*(-113) -35 + j*(-313) --267 + j*(-271) --388 + j*(52) --160 + j*(308) -133 + j*(223) -158 + j*(-12) -13 + j*(-76) --36 + j*(-8) --13 + j*(6) --27 + j*(-4) --44 + j*(18) --49 + j*(32) --75 + j*(81) --13 + j*(182) -148 + j*(168) -200 + j*(19) -131 + j*(-46) -139 + j*(-54) -121 + j*(-175) --78 + j*(-204) --154 + j*(7) -37 + j*(87) -86 + j*(-81) --64 + j*(-85) --6 + j*(43) -111 + j*(-93) --103 + j*(-233) --294 + j*(11) --91 + j*(235) -106 + j*(117) -64 + j*(27) -110 + j*(53) -191 + j*(-95) -31 + j*(-250) --144 + j*(-170) --157 + j*(-76) --209 + j*(-36) --236 + j*(128) --69 + j*(251) -84 + j*(177) -125 + j*(95) -177 + j*(-8) -71 + j*(-192) --204 + j*(-117) --164 + j*(200) -153 + j*(187) -148 + j*(-98) --88 + j*(-79) --40 + j*(113) -110 + j*(35) -11 + j*(-76) --71 + j*(46) -70 + j*(124) -175 + j*(-5) -114 + j*(-146) --22 + j*(-192) --167 + j*(-117) --182 + j*(71) --16 + j*(154) -81 + j*(30) --27 + j*(-45) --94 + j*(90) -71 + j*(202) -274 + j*(52) -215 + j*(-234) --93 + j*(-301) --268 + j*(-52) --110 + j*(161) -73 + j*(81) -32 + j*(-45) --45 + j*(-16) --29 + j*(23) --31 + j*(35) -9 + j*(85) -100 + j*(33) -43 + j*(-78) --61 + j*(1) -64 + j*(94) -168 + j*(-78) --13 + j*(-205) --144 + j*(-61) --56 + j*(13) --86 + j*(-42) --156 + j*(94) -42 + j*(208) -191 + j*(-6) --13 + j*(-153) --127 + j*(37) -59 + j*(109) -88 + j*(-75) --93 + j*(-64) --45 + j*(118) -148 + j*(40) -61 + j*(-171) --164 + j*(-104) --133 + j*(106) -27 + j*(103) -9 + j*(1) --65 + j*(74) -59 + j*(178) -222 + j*(57) -158 + j*(-132) -12 + j*(-125) -33 + j*(-59) -55 + j*(-160) --129 + j*(-214) --256 + j*(-8) --85 + j*(175) -112 + j*(47) -15 + j*(-156) --210 + j*(-97) --221 + j*(140) --15 + j*(230) -112 + j*(87) -8 + j*(-23) --72 + j*(98) -100 + j*(187) -235 + j*(-24) -18 + j*(-221) --236 + j*(-31) --109 + j*(274) -211 + j*(248) -299 + j*(-25) -122 + j*(-179) --27 + j*(-86) -56 + j*(40) -208 + j*(-78) -81 + j*(-318) --235 + j*(-260) --277 + j*(49) --59 + j*(149) -13 + j*(44) --18 + j*(52) -71 + j*(60) -81 + j*(-71) --65 + j*(-76) --45 + j*(76) -122 + j*(35) -91 + j*(-156) --100 + j*(-170) --175 + j*(-18) --83 + j*(103) -70 + j*(66) -72 + j*(-126) --162 + j*(-174) --268 + j*(81) --34 + j*(223) -95 + j*(27) --81 + j*(-58) --129 + j*(103) --10 + j*(121) --62 + j*(67) --89 + j*(242) -182 + j*(332) -387 + j*(71) -248 + j*(-204) --4 + j*(-214) --124 + j*(-41) --28 + j*(148) -207 + j*(115) -240 + j*(-131) -43 + j*(-199) -14 + j*(-80) -99 + j*(-156) --59 + j*(-278) --228 + j*(-122) --134 + j*(25) --71 + j*(-31) --134 + j*(-13) --91 + j*(50) --78 + j*(2) --161 + j*(66) --52 + j*(206) -125 + j*(95) -28 + j*(-72) --110 + j*(14) --52 + j*(128) -25 + j*(127) -94 + j*(114) -146 + j*(-5) --8 + j*(-91) --98 + j*(117) -173 + j*(220) -301 + j*(-74) -52 + j*(-197) -16 + j*(-13) -180 + j*(-112) --13 + j*(-313) --245 + j*(-104) --64 + j*(89) -49 + j*(-84) --145 + j*(-141) --194 + j*(45) --72 + j*(105) --32 + j*(76) -17 + j*(74) -37 + j*(-18) --81 + j*(-42) --104 + j*(80) --23 + j*(100) --51 + j*(107) -42 + j*(243) -305 + j*(128) -233 + j*(-210) --93 + j*(-184) --76 + j*(74) -112 + j*(35) -50 + j*(-95) --22 + j*(-21) -63 + j*(-1) -66 + j*(-93) -1 + j*(-117) --45 + j*(-119) --119 + j*(-73) --69 + j*(36) -47 + j*(-61) --136 + j*(-212) --364 + j*(19) --169 + j*(305) -76 + j*(196) -14 + j*(92) -61 + j*(190) -235 + j*(61) -98 + j*(-155) --96 + j*(-29) -35 + j*(119) -154 + j*(-23) -37 + j*(-140) --79 + j*(-98) --150 + j*(-16) --151 + j*(161) -73 + j*(278) -285 + j*(93) -202 + j*(-139) -32 + j*(-159) --49 + j*(-87) --57 + j*(21) -84 + j*(85) -197 + j*(-92) -2 + j*(-245) --152 + j*(-64) -23 + j*(43) -71 + j*(-156) --158 + j*(-175) --177 + j*(49) -2 + j*(60) --1 + j*(-68) --82 + j*(-66) --103 + j*(-56) --190 + j*(-33) --222 + j*(119) --102 + j*(221) --3 + j*(219) -112 + j*(226) -266 + j*(72) -149 + j*(-171) --91 + j*(-102) --21 + j*(69) -61 + j*(-51) --136 + j*(-63) --110 + j*(204) -182 + j*(163) -125 + j*(-103) --85 + j*(6) -95 + j*(177) -266 + j*(-32) -110 + j*(-194) -34 + j*(-147) -1 + j*(-245) --282 + j*(-225) --354 + j*(159) -15 + j*(309) -162 + j*(33) --21 + j*(-33) -23 + j*(92) -115 + j*(-56) --123 + j*(-117) --177 + j*(212) -219 + j*(306) -383 + j*(-83) -90 + j*(-290) --67 + j*(-128) -14 + j*(-94) --74 + j*(-182) --212 + j*(-44) --86 + j*(112) -40 + j*(11) --71 + j*(-66) --117 + j*(74) -45 + j*(103) -53 + j*(-76) --162 + j*(-62) --153 + j*(212) -172 + j*(257) -296 + j*(-73) -11 + j*(-260) --197 + j*(-38) --28 + j*(155) -134 + j*(14) -11 + j*(-101) --45 + j*(18) -98 + j*(8) -37 + j*(-184) --190 + j*(-105) --107 + j*(119) -73 + j*(1) --116 + j*(-134) --236 + j*(137) -83 + j*(258) -188 + j*(-74) --141 + j*(-133) --141 + j*(196) -178 + j*(144) -77 + j*(-153) --197 + j*(-9) --36 + j*(248) -184 + j*(119) -115 + j*(-14) -110 + j*(16) -146 + j*(-99) --31 + j*(-158) --87 + j*(29) -91 + j*(44) -52 + j*(-133) --122 + j*(-55) --30 + j*(98) -74 + j*(4) --31 + j*(-33) --4 + j*(100) -165 + j*(47) -131 + j*(-136) --23 + j*(-144) --62 + j*(-45) --7 + j*(18) -103 + j*(-16) -102 + j*(-202) --154 + j*(-264) --269 + j*(8) --14 + j*(118) -39 + j*(-144) --268 + j*(-148) --272 + j*(185) -19 + j*(200) --1 + j*(0) --125 + j*(96) -30 + j*(173) -55 + j*(-4) --146 + j*(56) --10 + j*(319) -322 + j*(182) -257 + j*(-162) --13 + j*(-180) --65 + j*(-35) --40 + j*(-1) --58 + j*(54) -21 + j*(128) -138 + j*(82) -168 + j*(-33) -116 + j*(-145) --39 + j*(-184) --156 + j*(-38) --47 + j*(105) -68 + j*(25) --13 + j*(-14) -35 + j*(111) -247 + j*(3) -142 + j*(-295) --182 + j*(-240) --173 + j*(28) -1 + j*(16) --51 + j*(-80) --89 + j*(-8) --27 + j*(-38) --166 + j*(-100) --269 + j*(147) -30 + j*(319) -247 + j*(24) --16 + j*(-187) --190 + j*(47) -23 + j*(173) -90 + j*(-25) --108 + j*(-33) --93 + j*(188) -130 + j*(202) -206 + j*(45) -183 + j*(-49) -161 + j*(-170) --33 + j*(-283) --267 + j*(-117) --189 + j*(159) -41 + j*(152) -41 + j*(3) --54 + j*(52) -41 + j*(136) -129 + j*(34) -35 + j*(-28) -20 + j*(85) -183 + j*(83) -219 + j*(-107) -69 + j*(-186) -3 + j*(-112) -37 + j*(-106) -4 + j*(-153) --51 + j*(-147) --91 + j*(-144) --175 + j*(-95) --158 + j*(46) --6 + j*(42) --35 + j*(-116) --227 + j*(-52) --151 + j*(165) -64 + j*(83) --52 + j*(-116) --252 + j*(39) --90 + j*(250) -103 + j*(104) --49 + j*(-39) --174 + j*(150) -37 + j*(317) -267 + j*(153) -196 + j*(-101) --31 + j*(-114) --81 + j*(76) -90 + j*(135) -138 + j*(-33) --36 + j*(-49) --8 + j*(163) -263 + j*(107) -215 + j*(-211) --100 + j*(-178) --57 + j*(99) -180 + j*(23) -81 + j*(-173) --51 + j*(-57) -98 + j*(-8) -91 + j*(-219) --158 + j*(-207) --163 + j*(16) --11 + j*(6) --74 + j*(-83) --141 + j*(24) --35 + j*(77) --21 + j*(10) --57 + j*(75) -102 + j*(112) -183 + j*(-119) --65 + j*(-275) --282 + j*(-79) --187 + j*(134) --65 + j*(109) --110 + j*(112) --45 + j*(265) -230 + j*(242) -305 + j*(-80) -11 + j*(-239) --171 + j*(6) -42 + j*(171) -181 + j*(-25) -2 + j*(-136) --69 + j*(27) -86 + j*(60) -97 + j*(-74) -13 + j*(-67) -77 + j*(-61) -39 + j*(-223) --218 + j*(-214) --292 + j*(66) --76 + j*(206) -69 + j*(94) -37 + j*(-4) --6 + j*(-4) -2 + j*(16) -38 + j*(-16) --6 + j*(-115) --191 + j*(-93) --235 + j*(159) -21 + j*(279) -175 + j*(70) -17 + j*(-56) --59 + j*(85) -85 + j*(141) -148 + j*(23) -102 + j*(-33) -99 + j*(-64) -39 + j*(-146) --107 + j*(-110) --124 + j*(42) --4 + j*(92) -40 + j*(16) --25 + j*(-8) --51 + j*(77) -54 + j*(139) -168 + j*(46) -113 + j*(-96) --28 + j*(-76) --30 + j*(47) -65 + j*(81) -136 + j*(57) -230 + j*(-17) -228 + j*(-216) -7 + j*(-314) --117 + j*(-148) -7 + j*(-106) --64 + j*(-285) --361 + j*(-161) --272 + j*(223) -129 + j*(195) -146 + j*(-167) --153 + j*(-218) --223 + j*(-16) --141 + j*(37) --156 + j*(42) --127 + j*(127) --32 + j*(117) --32 + j*(57) --54 + j*(74) --26 + j*(62) --93 + j*(35) --158 + j*(176) -22 + j*(332) -271 + j*(197) -228 + j*(-80) --19 + j*(-112) --82 + j*(104) -122 + j*(197) -270 + j*(11) -146 + j*(-187) --59 + j*(-143) --78 + j*(24) -31 + j*(86) -126 + j*(44) -180 + j*(-72) -92 + j*(-243) --170 + j*(-241) --284 + j*(40) --55 + j*(232) -149 + j*(73) -33 + j*(-94) --103 + j*(19) -11 + j*(149) -144 + j*(65) -103 + j*(-41) -56 + j*(-19) -107 + j*(-18) -112 + j*(-110) -12 + j*(-151) --49 + j*(-78) -7 + j*(-21) -65 + j*(-89) --4 + j*(-190) --156 + j*(-168) --218 + j*(-20) --136 + j*(106) --19 + j*(116) -57 + j*(67) -105 + j*(-18) -68 + j*(-156) --119 + j*(-213) --281 + j*(-46) --193 + j*(177) -11 + j*(179) -53 + j*(48) --5 + j*(34) -45 + j*(67) -104 + j*(-28) -14 + j*(-131) --103 + j*(-93) --124 + j*(-23) --140 + j*(9) --147 + j*(88) --59 + j*(136) --20 + j*(49) --163 + j*(47) --187 + j*(293) -126 + j*(425) -369 + j*(152) -197 + j*(-113) --4 + j*(-4) -114 + j*(127) -217 + j*(-8) -110 + j*(-86) -119 + j*(-16) -207 + j*(-158) --29 + j*(-351) --351 + j*(-115) --214 + j*(274) -127 + j*(270) -202 + j*(71) -164 + j*(25) -209 + j*(-23) -180 + j*(-123) -125 + j*(-127) -163 + j*(-175) -66 + j*(-309) --121 + j*(-241) --70 + j*(-93) -13 + j*(-209) --196 + j*(-296) --332 + j*(-61) --144 + j*(71) --88 + j*(-83) --279 + j*(-66) --269 + j*(167) --64 + j*(204) --10 + j*(82) --59 + j*(57) --69 + j*(72) --88 + j*(90) --69 + j*(161) -24 + j*(179) -76 + j*(122) -96 + j*(81) -103 + j*(7) -4 + j*(-44) --62 + j*(68) -54 + j*(134) -95 + j*(29) -12 + j*(61) -164 + j*(158) -338 + j*(-107) -28 + j*(-395) --340 + j*(-124) --163 + j*(250) -137 + j*(159) -92 + j*(-22) -24 + j*(29) -103 + j*(35) -98 + j*(-47) -66 + j*(-48) -89 + j*(-93) --3 + j*(-174) --129 + j*(-92) --98 + j*(28) --38 + j*(42) --7 + j*(63) -78 + j*(34) -50 + j*(-86) --81 + j*(-46) --16 + j*(85) -103 + j*(-8) --16 + j*(-98) --54 + j*(54) -149 + j*(39) -102 + j*(-221) --192 + j*(-181) --167 + j*(105) -78 + j*(81) -42 + j*(-127) --145 + j*(-88) --132 + j*(79) -8 + j*(108) -81 + j*(4) -7 + j*(-110) --141 + j*(-67) --123 + j*(97) -32 + j*(84) --13 + j*(-54) --156 + j*(39) --35 + j*(213) -158 + j*(103) -86 + j*(-72) --36 + j*(-31) --8 + j*(33) -12 + j*(3) --18 + j*(3) --26 + j*(21) --40 + j*(49) --1 + j*(110) -91 + j*(77) -57 + j*(-6) -1 + j*(72) -150 + j*(144) -295 + j*(-41) -176 + j*(-265) --59 + j*(-291) --229 + j*(-135) --201 + j*(130) -114 + j*(213) -281 + j*(-125) --55 + j*(-348) --282 + j*(-45) --9 + j*(112) -31 + j*(-186) --354 + j*(-137) --294 + j*(325) -173 + j*(303) -168 + j*(-91) --138 + j*(-62) --81 + j*(177) -95 + j*(133) -79 + j*(59) -144 + j*(83) -242 + j*(-95) -37 + j*(-299) --247 + j*(-161) --223 + j*(132) -5 + j*(216) -146 + j*(88) -110 + j*(-48) -15 + j*(-57) -13 + j*(1) -62 + j*(-21) -42 + j*(-80) --10 + j*(-93) --57 + j*(-95) --132 + j*(-48) --117 + j*(71) --4 + j*(81) --21 + j*(-1) --98 + j*(76) -10 + j*(199) -175 + j*(142) -238 + j*(12) -245 + j*(-152) -62 + j*(-344) --260 + j*(-221) --199 + j*(131) -117 + j*(80) -23 + j*(-192) --208 + j*(-39) --1 + j*(132) -88 + j*(-134) --250 + j*(-153) --228 + j*(236) -160 + j*(183) -52 + j*(-163) --254 + j*(30) -9 + j*(329) -326 + j*(51) -100 + j*(-272) --187 + j*(-156) --197 + j*(35) --144 + j*(139) --6 + j*(221) -158 + j*(98) -41 + j*(-88) --153 + j*(50) --9 + j*(281) -256 + j*(204) -310 + j*(-22) -224 + j*(-184) -53 + j*(-279) --167 + j*(-194) --196 + j*(51) --12 + j*(165) -132 + j*(88) -176 + j*(-17) -170 + j*(-149) -28 + j*(-263) --156 + j*(-184) --144 + j*(-11) --22 + j*(-8) --47 + j*(-112) --171 + j*(-77) --164 + j*(60) --51 + j*(81) --47 + j*(-8) --152 + j*(21) --140 + j*(176) -28 + j*(229) -139 + j*(130) -151 + j*(42) -165 + j*(-37) -103 + j*(-161) --70 + j*(-179) --158 + j*(-38) --97 + j*(66) --30 + j*(76) -13 + j*(75) -59 + j*(37) -47 + j*(-21) -20 + j*(-23) -34 + j*(-53) --50 + j*(-124) --206 + j*(-18) --139 + j*(218) -118 + j*(235) -202 + j*(41) -112 + j*(-37) -115 + j*(-7) -166 + j*(-97) -34 + j*(-267) --239 + j*(-119) --108 + j*(65) --68 + j*(-85) --296 + j*(1) --157 + j*(327) -224 + j*(201) -135 + j*(-182) --231 + j*(-141) --275 + j*(192) --20 + j*(354) -240 + j*(245) -291 + j*(-37) -54 + j*(-195) --135 + j*(-11) -25 + j*(170) -205 + j*(23) -100 + j*(-162) --71 + j*(-133) --131 + j*(-20) --115 + j*(113) -40 + j*(216) -250 + j*(104) -235 + j*(-154) -15 + j*(-248) --147 + j*(-132) --148 + j*(35) --17 + j*(121) -110 + j*(30) -44 + j*(-112) --106 + j*(-56) --55 + j*(97) -101 + j*(49) -62 + j*(-112) --109 + j*(-88) --120 + j*(91) -51 + j*(150) -152 + j*(11) -57 + j*(-103) --35 + j*(-41) -23 + j*(16) -52 + j*(-61) --41 + j*(-70) --28 + j*(37) -96 + j*(8) -76 + j*(-127) --33 + j*(-134) --47 + j*(-99) --90 + j*(-128) --177 + j*(-52) --112 + j*(59) --25 + j*(-8) --124 + j*(-69) --187 + j*(62) --61 + j*(129) --21 + j*(21) --146 + j*(18) --155 + j*(183) -16 + j*(247) -124 + j*(129) -52 + j*(31) --17 + j*(124) -143 + j*(221) -337 + j*(25) -185 + j*(-251) --93 + j*(-180) --52 + j*(13) -37 + j*(-83) --168 + j*(-117) --214 + j*(187) -127 + j*(282) -261 + j*(-25) -44 + j*(-146) --10 + j*(-31) -24 + j*(-95) --183 + j*(-95) --222 + j*(240) -168 + j*(390) -433 + j*(71) -298 + j*(-221) -113 + j*(-276) --38 + j*(-285) --211 + j*(-148) --129 + j*(102) -140 + j*(42) -71 + j*(-243) --246 + j*(-169) --197 + j*(172) -141 + j*(163) -176 + j*(-131) --39 + j*(-188) --71 + j*(-68) --6 + j*(-113) --122 + j*(-194) --250 + j*(-72) --182 + j*(49) --130 + j*(2) --233 + j*(1) --279 + j*(167) --152 + j*(306) -4 + j*(311) -115 + j*(258) -196 + j*(161) -183 + j*(35) -96 + j*(2) -91 + j*(52) -163 + j*(17) -135 + j*(-98) -13 + j*(-98) -6 + j*(10) -126 + j*(-1) -124 + j*(-168) --72 + j*(-218) --180 + j*(-43) --50 + j*(76) -38 + j*(-34) --102 + j*(-103) --193 + j*(77) --8 + j*(222) -180 + j*(76) -91 + j*(-114) --70 + j*(-62) --25 + j*(64) -83 + j*(8) -17 + j*(-104) --108 + j*(-43) --68 + j*(95) -66 + j*(85) -87 + j*(-28) -7 + j*(-65) --32 + j*(-13) -8 + j*(21) -50 + j*(-14) -21 + j*(-77) --58 + j*(-66) --64 + j*(24) -18 + j*(32) -10 + j*(-45) --84 + j*(0) --7 + j*(138) -182 + j*(66) -154 + j*(-149) --35 + j*(-161) --43 + j*(-35) -47 + j*(-86) --53 + j*(-212) --228 + j*(-121) --199 + j*(75) --38 + j*(105) --4 + j*(0) --91 + j*(-20) --118 + j*(69) --45 + j*(129) -31 + j*(110) -70 + j*(59) -72 + j*(-11) -1 + j*(-50) --55 + j*(21) -40 + j*(91) -129 + j*(-38) --18 + j*(-161) --184 + j*(-22) --86 + j*(154) -49 + j*(109) -23 + j*(70) -81 + j*(145) -249 + j*(54) -211 + j*(-182) --6 + j*(-238) --119 + j*(-112) --94 + j*(-16) --45 + j*(4) --40 + j*(-24) --111 + j*(-7) --115 + j*(140) -83 + j*(215) -242 + j*(36) -144 + j*(-174) --55 + j*(-186) --177 + j*(-56) --151 + j*(151) -97 + j*(248) -300 + j*(8) -105 + j*(-250) --141 + j*(-107) --28 + j*(91) -112 + j*(-6) -44 + j*(-77) -77 + j*(-43) -118 + j*(-206) --136 + j*(-317) --323 + j*(-78) --179 + j*(105) --104 + j*(43) --173 + j*(98) --71 + j*(229) -88 + j*(177) -116 + j*(83) -140 + j*(18) -84 + j*(-103) --86 + j*(-54) --16 + j*(139) -209 + j*(42) -120 + j*(-204) --91 + j*(-161) --88 + j*(-69) --161 + j*(-97) --286 + j*(111) --36 + j*(347) -242 + j*(135) -69 + j*(-81) --37 + j*(124) -262 + j*(174) -354 + j*(-204) -2 + j*(-390) --237 + j*(-170) --171 + j*(34) --58 + j*(66) --5 + j*(24) --40 + j*(-21) --98 + j*(57) -17 + j*(168) -192 + j*(62) -145 + j*(-131) -6 + j*(-157) --46 + j*(-134) --132 + j*(-122) --197 + j*(14) --73 + j*(123) -19 + j*(25) --85 + j*(-29) --125 + j*(93) --18 + j*(140) -16 + j*(88) -4 + j*(108) -71 + j*(125) -114 + j*(65) -103 + j*(39) -145 + j*(17) -142 + j*(-93) -8 + j*(-139) --78 + j*(-27) --11 + j*(73) -76 + j*(73) -147 + j*(40) -218 + j*(-68) -157 + j*(-252) --81 + j*(-305) --247 + j*(-103) --129 + j*(117) -89 + j*(69) -76 + j*(-133) --103 + j*(-138) --116 + j*(15) --3 + j*(2) --71 + j*(-87) --168 + j*(54) -42 + j*(187) -231 + j*(-71) --33 + j*(-334) --361 + j*(-124) --255 + j*(204) --13 + j*(185) --21 + j*(64) --66 + j*(123) -37 + j*(165) -95 + j*(77) -58 + j*(33) -67 + j*(37) -74 + j*(-26) --30 + j*(-59) --108 + j*(63) -1 + j*(209) -211 + j*(170) -277 + j*(-49) -127 + j*(-202) --37 + j*(-149) --49 + j*(-40) --4 + j*(-18) -2 + j*(-22) -18 + j*(-16) -25 + j*(-37) -17 + j*(-31) -79 + j*(-47) -69 + j*(-206) --183 + j*(-267) --346 + j*(2) --140 + j*(216) -21 + j*(79) --124 + j*(21) --123 + j*(237) -144 + j*(259) -203 + j*(23) -47 + j*(-21) -65 + j*(90) -180 + j*(37) -152 + j*(-79) -76 + j*(-94) -55 + j*(-66) -95 + j*(-49) -170 + j*(-146) -53 + j*(-356) --285 + j*(-315) --371 + j*(47) --97 + j*(212) -49 + j*(59) --17 + j*(-6) --7 + j*(9) --35 + j*(-49) --129 + j*(38) -21 + j*(176) -208 + j*(-23) -5 + j*(-260) --254 + j*(-107) --191 + j*(100) --117 + j*(107) --118 + j*(190) -64 + j*(272) -217 + j*(83) -73 + j*(-70) --32 + j*(52) -101 + j*(117) -176 + j*(-16) -87 + j*(-118) --18 + j*(-108) --82 + j*(-35) --58 + j*(65) -35 + j*(84) -73 + j*(41) -102 + j*(31) -163 + j*(-49) -85 + j*(-190) --89 + j*(-156) --95 + j*(-13) --11 + j*(-6) --22 + j*(-48) --49 + j*(-43) --93 + j*(-39) --145 + j*(78) -29 + j*(209) -235 + j*(17) -60 + j*(-231) --168 + j*(-93) --69 + j*(47) --81 + j*(-54) --246 + j*(132) -73 + j*(419) -487 + j*(60) -174 + j*(-421) --269 + j*(-190) --85 + j*(129) -81 + j*(-65) --154 + j*(-115) --136 + j*(141) -96 + j*(64) --59 + j*(-118) --215 + j*(124) -84 + j*(286) -255 + j*(-15) --16 + j*(-170) --146 + j*(68) -57 + j*(194) -195 + j*(58) -163 + j*(-68) -100 + j*(-120) -36 + j*(-140) --8 + j*(-136) --66 + j*(-155) --198 + j*(-103) --226 + j*(107) --17 + j*(230) -150 + j*(91) -87 + j*(-49) -8 + j*(-22) -44 + j*(16) -93 + j*(-31) -83 + j*(-126) --42 + j*(-206) --228 + j*(-101) --180 + j*(163) -112 + j*(176) -170 + j*(-102) --66 + j*(-179) --119 + j*(-8) -2 + j*(-32) --122 + j*(-159) --315 + j*(13) --185 + j*(263) -39 + j*(226) -61 + j*(107) -42 + j*(103) -80 + j*(82) -66 + j*(42) -73 + j*(47) -92 + j*(-11) --8 + j*(-42) --36 + j*(92) -136 + j*(116) -161 + j*(-85) --52 + j*(-107) --78 + j*(107) -115 + j*(158) -198 + j*(37) -206 + j*(-30) -233 + j*(-147) -105 + j*(-296) --91 + j*(-243) --107 + j*(-116) --93 + j*(-111) --156 + j*(-58) --100 + j*(51) --8 + j*(5) --76 + j*(-36) --76 + j*(80) -89 + j*(67) -88 + j*(-130) --109 + j*(-154) --163 + j*(4) --71 + j*(72) --11 + j*(50) -28 + j*(6) -4 + j*(-98) --163 + j*(-115) --266 + j*(84) --107 + j*(284) -148 + j*(235) -229 + j*(-1) -65 + j*(-182) --173 + j*(-113) --206 + j*(139) -15 + j*(269) -215 + j*(127) -177 + j*(-83) -16 + j*(-129) --66 + j*(-47) --53 + j*(12) --54 + j*(39) --33 + j*(121) -116 + j*(142) -199 + j*(-38) -25 + j*(-173) --127 + j*(-29) --23 + j*(112) -71 + j*(55) -71 + j*(41) -174 + j*(1) -127 + j*(-229) --209 + j*(-211) --235 + j*(178) -154 + j*(242) -226 + j*(-96) --25 + j*(-138) --1 + j*(19) -86 + j*(-87) --87 + j*(-129) --107 + j*(76) -92 + j*(91) -117 + j*(-59) -75 + j*(-100) -46 + j*(-206) --205 + j*(-226) --292 + j*(119) -88 + j*(243) -202 + j*(-139) --165 + j*(-208) --170 + j*(136) -146 + j*(70) -25 + j*(-223) --239 + j*(-89) --125 + j*(107) --38 + j*(11) --151 + j*(28) --81 + j*(168) -54 + j*(91) --25 + j*(-14) --119 + j*(71) --67 + j*(187) -62 + j*(231) -211 + j*(141) -182 + j*(-53) -4 + j*(-33) -92 + j*(132) -301 + j*(-38) -110 + j*(-316) --187 + j*(-183) --132 + j*(46) --33 + j*(34) --54 + j*(67) -66 + j*(127) -159 + j*(-26) -22 + j*(-117) --34 + j*(-18) -18 + j*(-16) --23 + j*(-11) -64 + j*(69) -196 + j*(-114) --57 + j*(-320) --330 + j*(-72) --152 + j*(192) --2 + j*(98) --83 + j*(132) -121 + j*(293) -404 + j*(18) -167 + j*(-352) --204 + j*(-215) --169 + j*(91) -43 + j*(148) -187 + j*(39) -197 + j*(-179) --52 + j*(-305) --244 + j*(-71) --23 + j*(115) -124 + j*(-132) --166 + j*(-276) --333 + j*(7) --122 + j*(169) --35 + j*(35) --150 + j*(45) --89 + j*(186) -71 + j*(132) -36 + j*(-23) --124 + j*(-6) --153 + j*(177) -23 + j*(295) -215 + j*(187) -194 + j*(6) -92 + j*(1) -140 + j*(35) -164 + j*(-89) -0 + j*(-136) --56 + j*(47) -154 + j*(107) -251 + j*(-138) -10 + j*(-301) --205 + j*(-109) --66 + j*(111) -130 + j*(-16) --21 + j*(-204) --230 + j*(-14) --6 + j*(218) -248 + j*(-33) --30 + j*(-313) --336 + j*(-28) --74 + j*(287) -214 + j*(66) -23 + j*(-171) --169 + j*(6) --18 + j*(186) -165 + j*(110) -215 + j*(-51) -141 + j*(-221) --84 + j*(-267) --209 + j*(-71) --64 + j*(42) --12 + j*(-101) --207 + j*(-122) --271 + j*(94) --121 + j*(217) --10 + j*(194) -59 + j*(175) -134 + j*(99) -99 + j*(0) -27 + j*(18) -67 + j*(83) -180 + j*(54) -252 + j*(-110) -118 + j*(-344) --245 + j*(-345) --413 + j*(30) --139 + j*(291) -91 + j*(139) --4 + j*(32) -15 + j*(153) -206 + j*(59) -92 + j*(-194) --200 + j*(-92) --145 + j*(218) -156 + j*(247) -284 + j*(16) -176 + j*(-186) --37 + j*(-201) --136 + j*(-23) -21 + j*(102) -150 + j*(-71) --67 + j*(-228) --292 + j*(19) --73 + j*(336) -310 + j*(216) -332 + j*(-157) -56 + j*(-287) --94 + j*(-136) --10 + j*(-37) -43 + j*(-132) --78 + j*(-206) --198 + j*(-115) --190 + j*(-6) --173 + j*(41) --153 + j*(139) -8 + j*(206) -163 + j*(44) -36 + j*(-164) --196 + j*(-98) --203 + j*(114) --78 + j*(181) --26 + j*(182) -62 + j*(232) -237 + j*(156) -251 + j*(-74) -62 + j*(-168) --41 + j*(-62) -3 + j*(-13) --21 + j*(-46) --76 + j*(36) -42 + j*(139) -205 + j*(18) -135 + j*(-199) --91 + j*(-214) --186 + j*(-43) --100 + j*(76) --15 + j*(37) --72 + j*(-13) --146 + j*(102) --11 + j*(252) -202 + j*(170) -194 + j*(-18) -103 + j*(-23) -181 + j*(-23) -166 + j*(-228) --115 + j*(-272) --225 + j*(10) -1 + j*(140) -100 + j*(-16) --1 + j*(-50) -47 + j*(25) -138 + j*(-90) -16 + j*(-223) --127 + j*(-161) --138 + j*(-84) --164 + j*(-64) --204 + j*(10) --188 + j*(89) --175 + j*(176) --53 + j*(317) -230 + j*(272) -305 + j*(-43) -55 + j*(-187) --64 + j*(-13) -90 + j*(30) -88 + j*(-156) --129 + j*(-174) --196 + j*(16) --98 + j*(94) --83 + j*(88) --60 + j*(185) -122 + j*(215) -223 + j*(18) -56 + j*(-102) --25 + j*(59) -197 + j*(101) -256 + j*(-204) --93 + j*(-337) --296 + j*(-22) --63 + j*(194) -100 + j*(45) --1 + j*(-23) -26 + j*(77) -159 + j*(-20) -41 + j*(-190) --141 + j*(-94) --85 + j*(64) -17 + j*(31) --13 + j*(-13) --18 + j*(30) -35 + j*(13) -6 + j*(-37) --47 + j*(8) -11 + j*(77) -110 + j*(32) -112 + j*(-88) -20 + j*(-143) --46 + j*(-119) --78 + j*(-110) --158 + j*(-88) --196 + j*(45) --78 + j*(132) -3 + j*(45) --91 + j*(6) --100 + j*(129) -20 + j*(136) --5 + j*(57) --52 + j*(176) -173 + j*(255) -332 + j*(-16) -96 + j*(-234) --121 + j*(-66) --5 + j*(100) -100 + j*(18) -38 + j*(-21) -70 + j*(42) -169 + j*(-37) -86 + j*(-180) --71 + j*(-134) --54 + j*(-3) -48 + j*(-19) -24 + j*(-111) --67 + j*(-94) --61 + j*(-22) --18 + j*(-33) --43 + j*(-50) --28 + j*(-21) -10 + j*(-98) --150 + j*(-191) --346 + j*(9) --187 + j*(305) -134 + j*(229) -122 + j*(-38) --75 + j*(-45) --81 + j*(108) -35 + j*(128) -87 + j*(60) -73 + j*(-12) --1 + j*(-37) --43 + j*(38) -37 + j*(85) -69 + j*(6) --5 + j*(9) -47 + j*(98) -168 + j*(11) -84 + j*(-131) --36 + j*(-69) -14 + j*(-11) -0 + j*(-80) --106 + j*(-10) --7 + j*(136) -168 + j*(38) -94 + j*(-140) --55 + j*(-88) -1 + j*(16) -88 + j*(-73) --23 + j*(-194) --198 + j*(-105) --177 + j*(92) --8 + j*(129) -30 + j*(16) --53 + j*(25) -8 + j*(119) -132 + j*(45) -78 + j*(-69) -28 + j*(-37) -82 + j*(-84) --40 + j*(-209) --239 + j*(-71) --139 + j*(154) -50 + j*(103) -24 + j*(-12) --9 + j*(5) --3 + j*(-36) --116 + j*(-28) --100 + j*(141) -89 + j*(119) -43 + j*(-52) --103 + j*(43) -37 + j*(163) -112 + j*(13) --36 + j*(25) -91 + j*(203) -330 + j*(-5) -105 + j*(-291) --171 + j*(-92) -3 + j*(132) -169 + j*(-21) -66 + j*(-124) -59 + j*(-92) -61 + j*(-216) --166 + j*(-260) --288 + j*(-28) --144 + j*(124) --42 + j*(82) --34 + j*(65) -1 + j*(53) --16 + j*(18) --38 + j*(60) -28 + j*(83) -56 + j*(20) -27 + j*(11) -66 + j*(15) -75 + j*(-78) --39 + j*(-118) --107 + j*(-30) --64 + j*(39) --19 + j*(25) --37 + j*(-17) --118 + j*(4) --134 + j*(147) -31 + j*(228) -143 + j*(97) -49 + j*(32) -76 + j*(151) -277 + j*(72) -225 + j*(-197) --33 + j*(-203) --60 + j*(-19) -44 + j*(-20) --1 + j*(-74) --28 + j*(-5) -49 + j*(11) -67 + j*(-62) -25 + j*(-95) --18 + j*(-107) --86 + j*(-66) --52 + j*(37) -77 + j*(2) -51 + j*(-151) --102 + j*(-160) --155 + j*(-52) --123 + j*(10) --77 + j*(35) --37 + j*(-19) --151 + j*(-78) --279 + j*(107) --80 + j*(320) -166 + j*(162) -40 + j*(-37) --87 + j*(115) -116 + j*(214) -234 + j*(-7) -59 + j*(-147) --79 + j*(-52) --74 + j*(62) -0 + j*(154) -177 + j*(139) -238 + j*(-76) -45 + j*(-194) --65 + j*(-65) -10 + j*(-18) --23 + j*(-69) --79 + j*(30) -66 + j*(104) -166 + j*(-57) -38 + j*(-192) --109 + j*(-149) --170 + j*(-40) --140 + j*(96) -20 + j*(132) -81 + j*(-31) --105 + j*(-83) --165 + j*(148) -92 + j*(245) -236 + j*(13) -61 + j*(-146) --80 + j*(-19) -27 + j*(107) -159 + j*(11) -81 + j*(-136) --73 + j*(-70) -13 + j*(98) -228 + j*(-10) -141 + j*(-288) --147 + j*(-269) --175 + j*(-65) --96 + j*(-78) --225 + j*(-78) --224 + j*(160) -59 + j*(181) -83 + j*(-113) --226 + j*(-141) --305 + j*(163) --93 + j*(317) -67 + j*(287) -216 + j*(245) -365 + j*(32) -216 + j*(-264) --116 + j*(-228) --151 + j*(48) -54 + j*(88) -63 + j*(-82) --107 + j*(-66) --95 + j*(116) -88 + j*(127) -116 + j*(-40) --36 + j*(-79) --89 + j*(66) -40 + j*(155) -170 + j*(84) -196 + j*(-43) -141 + j*(-147) -37 + j*(-197) --66 + j*(-172) --134 + j*(-96) --136 + j*(9) --40 + j*(70) -35 + j*(-16) --76 + j*(-89) --170 + j*(64) -11 + j*(190) -152 + j*(13) --12 + j*(-109) --90 + j*(52) -77 + j*(80) -54 + j*(-91) --123 + j*(-16) --5 + j*(180) -223 + j*(46) -123 + j*(-204) --119 + j*(-177) --174 + j*(16) --52 + j*(139) -118 + j*(87) -125 + j*(-110) --74 + j*(-159) --132 + j*(8) --10 + j*(21) --101 + j*(-79) --238 + j*(122) -15 + j*(330) -260 + j*(115) -121 + j*(-69) -85 + j*(38) -250 + j*(-74) -77 + j*(-341) --238 + j*(-199) --146 + j*(61) -8 + j*(-41) --161 + j*(-130) --271 + j*(75) --132 + j*(226) --8 + j*(225) -101 + j*(228) -247 + j*(119) -230 + j*(-91) -74 + j*(-165) --19 + j*(-128) --75 + j*(-95) --127 + j*(-25) --117 + j*(65) --79 + j*(142) -49 + j*(235) -298 + j*(139) -308 + j*(-222) --73 + j*(-368) --323 + j*(-56) --135 + j*(231) -115 + j*(166) -129 + j*(3) -47 + j*(-31) -39 + j*(25) -129 + j*(23) -165 + j*(-124) -3 + j*(-222) --131 + j*(-92) --35 + j*(14) -15 + j*(-88) --119 + j*(-105) --146 + j*(41) --48 + j*(86) --21 + j*(86) -78 + j*(122) -211 + j*(-35) -49 + j*(-244) --173 + j*(-111) --52 + j*(62) -48 + j*(-91) --158 + j*(-151) --210 + j*(82) -1 + j*(119) --11 + j*(-60) --188 + j*(6) --103 + j*(201) -93 + j*(146) -90 + j*(-23) --31 + j*(-64) --115 + j*(-6) --129 + j*(91) --73 + j*(156) --34 + j*(175) -8 + j*(250) -199 + j*(287) -373 + j*(81) -259 + j*(-160) -71 + j*(-150) -55 + j*(-83) -28 + j*(-115) --59 + j*(-50) -13 + j*(64) -136 + j*(-8) -74 + j*(-134) --45 + j*(-95) --34 + j*(8) -62 + j*(33) -138 + j*(-57) -73 + j*(-204) --126 + j*(-192) --165 + j*(19) -34 + j*(80) -88 + j*(-112) --105 + j*(-161) --154 + j*(27) -13 + j*(75) -53 + j*(-72) --76 + j*(-108) --110 + j*(0) --18 + j*(25) -4 + j*(-70) --103 + j*(-115) --195 + j*(-31) --182 + j*(82) --122 + j*(148) --19 + j*(197) -145 + j*(121) -130 + j*(-141) --204 + j*(-209) --380 + j*(159) --49 + j*(431) -254 + j*(199) -109 + j*(-46) --40 + j*(69) -76 + j*(146) -103 + j*(42) -23 + j*(88) -150 + j*(185) -306 + j*(30) -202 + j*(-156) -64 + j*(-117) -97 + j*(-59) -127 + j*(-127) -59 + j*(-185) --7 + j*(-177) --52 + j*(-165) --100 + j*(-148) --152 + j*(-111) --204 + j*(-42) --206 + j*(82) --100 + j*(183) -35 + j*(167) -95 + j*(85) -105 + j*(21) -103 + j*(-40) -58 + j*(-119) --71 + j*(-144) --182 + j*(-22) --114 + j*(151) -64 + j*(158) -118 + j*(35) -75 + j*(-1) -117 + j*(-11) -117 + j*(-136) --44 + j*(-187) --122 + j*(-53) --40 + j*(-3) --56 + j*(-62) --124 + j*(5) --46 + j*(85) -11 + j*(18) --49 + j*(7) --18 + j*(71) -37 + j*(21) --21 + j*(4) -23 + j*(83) -139 + j*(-21) -6 + j*(-177) --162 + j*(-49) --58 + j*(91) -13 + j*(4) --66 + j*(15) -26 + j*(85) -84 + j*(-81) --144 + j*(-136) --197 + j*(111) -9 + j*(126) --88 + j*(-19) --234 + j*(235) -132 + j*(465) -454 + j*(116) -223 + j*(-209) -18 + j*(-98) -71 + j*(-66) --54 + j*(-120) --129 + j*(120) -187 + j*(238) -367 + j*(-93) -122 + j*(-313) --61 + j*(-222) --101 + j*(-175) --223 + j*(-97) --185 + j*(135) -59 + j*(154) -94 + j*(-38) --36 + j*(-45) --3 + j*(41) -57 + j*(-8) -19 + j*(-36) -42 + j*(-23) -47 + j*(-97) --47 + j*(-107) --39 + j*(-42) --11 + j*(-113) --172 + j*(-134) --220 + j*(83) -5 + j*(147) -57 + j*(-65) --144 + j*(-103) --192 + j*(58) --134 + j*(111) --146 + j*(188) -15 + j*(324) -254 + j*(173) -148 + j*(-80) --52 + j*(23) -94 + j*(183) -257 + j*(17) -134 + j*(-141) -34 + j*(-82) -66 + j*(-64) -51 + j*(-109) -25 + j*(-139) --74 + j*(-213) --311 + j*(-86) --231 + j*(309) -259 + j*(319) -364 + j*(-181) --62 + j*(-348) --226 + j*(-56) --77 + j*(29) --122 + j*(-21) --134 + j*(138) -69 + j*(139) -33 + j*(-44) --113 + j*(81) -110 + j*(214) -250 + j*(-69) --32 + j*(-199) --103 + j*(50) -117 + j*(23) --11 + j*(-203) --255 + j*(-18) --77 + j*(229) -121 + j*(95) -27 + j*(-4) -33 + j*(86) -142 + j*(11) -57 + j*(-103) --25 + j*(-51) --18 + j*(-39) --105 + j*(-1) --42 + j*(191) -243 + j*(138) -227 + j*(-188) --71 + j*(-205) --73 + j*(17) -75 + j*(-42) --54 + j*(-156) --165 + j*(5) --11 + j*(103) -47 + j*(-25) --75 + j*(-35) --68 + j*(111) -99 + j*(136) -199 + j*(-17) -103 + j*(-174) --64 + j*(-142) --41 + j*(-4) -87 + j*(-76) --41 + j*(-238) --248 + j*(-98) --129 + j*(101) -1 + j*(-13) --146 + j*(-62) --127 + j*(126) -78 + j*(33) --100 + j*(-194) --372 + j*(47) --139 + j*(343) -95 + j*(155) --95 + j*(54) --81 + j*(323) -264 + j*(278) -234 + j*(-66) --50 + j*(-19) -48 + j*(223) -284 + j*(112) -224 + j*(-91) -134 + j*(-91) -138 + j*(-142) --8 + j*(-211) --136 + j*(-45) -19 + j*(98) -153 + j*(-49) -11 + j*(-176) --105 + j*(-61) --22 + j*(21) -2 + j*(-51) --99 + j*(-24) --56 + j*(127) -128 + j*(113) -160 + j*(-46) -81 + j*(-84) -115 + j*(-97) -65 + j*(-268) --238 + j*(-262) --328 + j*(115) -54 + j*(303) -318 + j*(-23) -104 + j*(-321) --145 + j*(-260) --211 + j*(-163) --313 + j*(-78) --312 + j*(160) --65 + j*(249) -25 + j*(66) --114 + j*(55) --45 + j*(205) -119 + j*(95) --11 + j*(-44) --98 + j*(122) -107 + j*(158) -88 + j*(-76) --170 + j*(13) --18 + j*(310) -313 + j*(129) -136 + j*(-189) --126 + j*(-7) -83 + j*(190) -230 + j*(-31) -31 + j*(-122) -38 + j*(31) -165 + j*(-95) --62 + j*(-211) --161 + j*(81) -185 + j*(142) -208 + j*(-250) --206 + j*(-253) --192 + j*(141) -153 + j*(92) -63 + j*(-202) --186 + j*(-95) --95 + j*(91) -0 + j*(26) --43 + j*(40) -65 + j*(83) -115 + j*(-91) --76 + j*(-152) --131 + j*(6) --35 + j*(12) --111 + j*(-40) --175 + j*(98) --62 + j*(197) -20 + j*(194) -148 + j*(226) -348 + j*(36) -168 + j*(-298) --222 + j*(-152) --85 + j*(243) -297 + j*(108) -188 + j*(-240) --70 + j*(-167) -7 + j*(-41) -28 + j*(-183) --185 + j*(-180) --223 + j*(41) --71 + j*(119) -10 + j*(57) -11 + j*(-16) --75 + j*(-59) --168 + j*(67) --23 + j*(224) -180 + j*(88) -67 + j*(-110) --99 + j*(-6) -11 + j*(132) -138 + j*(37) -91 + j*(-74) -19 + j*(-91) --42 + j*(-75) --66 + j*(5) -25 + j*(30) -19 + j*(-80) --114 + j*(-31) --13 + j*(120) -162 + j*(-45) --66 + j*(-266) --356 + j*(-14) --152 + j*(330) -183 + j*(220) -167 + j*(-35) -26 + j*(-68) --13 + j*(-28) --38 + j*(4) --9 + j*(59) -47 + j*(23) --9 + j*(-20) --32 + j*(76) -98 + j*(88) -107 + j*(-59) --37 + j*(-49) -12 + j*(94) -174 + j*(8) -88 + j*(-179) --100 + j*(-131) --91 + j*(10) --30 + j*(9) --70 + j*(28) --10 + j*(131) -158 + j*(77) -141 + j*(-124) --57 + j*(-151) --112 + j*(18) -19 + j*(88) -95 + j*(-1) -59 + j*(-68) -23 + j*(-81) --15 + j*(-88) --47 + j*(-52) --13 + j*(-25) -2 + j*(-80) --78 + j*(-100) --107 + j*(-23) --51 + j*(-14) --87 + j*(-75) --187 + j*(-18) --170 + j*(98) --112 + j*(129) --97 + j*(177) -15 + j*(250) -170 + j*(165) -148 + j*(12) -64 + j*(20) -124 + j*(47) -161 + j*(-74) -35 + j*(-153) --64 + j*(-81) --49 + j*(-13) --33 + j*(-3) --28 + j*(11) --21 + j*(12) --44 + j*(30) --15 + j*(107) -117 + j*(91) -134 + j*(-70) --36 + j*(-107) --75 + j*(66) -117 + j*(116) -204 + j*(-89) -24 + j*(-230) --148 + j*(-127) --139 + j*(30) --41 + j*(98) -69 + j*(69) -103 + j*(-61) --25 + j*(-137) --119 + j*(-23) --18 + j*(52) -8 + j*(-64) --153 + j*(-33) --83 + j*(189) -197 + j*(93) -86 + j*(-235) --293 + j*(-129) --226 + j*(281) -158 + j*(278) -195 + j*(-12) -13 + j*(-35) -42 + j*(86) -158 + j*(42) -163 + j*(-66) -129 + j*(-132) -66 + j*(-199) --32 + j*(-218) --116 + j*(-207) --245 + j*(-177) --373 + j*(11) --266 + j*(280) -18 + j*(331) -182 + j*(159) -158 + j*(-23) -15 + j*(-107) --128 + j*(-4) --47 + j*(170) -136 + j*(105) -69 + j*(-54) --55 + j*(49) -98 + j*(155) -208 + j*(-11) -83 + j*(-102) -73 + j*(-41) -92 + j*(-145) --116 + j*(-157) --128 + j*(124) -205 + j*(135) -236 + j*(-214) --62 + j*(-278) --117 + j*(-98) --63 + j*(-123) --197 + j*(-114) --185 + j*(81) --5 + j*(66) --50 + j*(-69) --143 + j*(8) --59 + j*(42) --122 + j*(-60) --296 + j*(93) --145 + j*(368) -175 + j*(320) -255 + j*(62) -122 + j*(-95) --64 + j*(-74) --113 + j*(142) -149 + j*(253) -330 + j*(-47) -31 + j*(-283) --222 + j*(-14) -6 + j*(216) -192 + j*(39) -72 + j*(-78) -43 + j*(-16) -64 + j*(-79) --71 + j*(-67) --28 + j*(125) -212 + j*(54) -131 + j*(-217) --133 + j*(-146) --68 + j*(70) -76 + j*(-16) --59 + j*(-91) --95 + j*(104) -144 + j*(139) -205 + j*(-93) -36 + j*(-150) -50 + j*(-59) -124 + j*(-183) --73 + j*(-305) --228 + j*(-122) --81 + j*(-23) --100 + j*(-214) --424 + j*(-128) --380 + j*(317) -73 + j*(366) -153 + j*(8) --98 + j*(-6) --1 + j*(191) -185 + j*(2) --50 + j*(-177) --202 + j*(67) -40 + j*(162) -50 + j*(-89) --235 + j*(-28) --160 + j*(301) -161 + j*(273) -180 + j*(40) -69 + j*(28) -107 + j*(59) -119 + j*(-6) -87 + j*(-18) -110 + j*(-49) -35 + j*(-127) --82 + j*(-34) -22 + j*(100) -173 + j*(-21) -50 + j*(-208) --171 + j*(-125) --165 + j*(105) -37 + j*(181) -170 + j*(35) -77 + j*(-113) --60 + j*(-45) -16 + j*(80) -151 + j*(-3) -94 + j*(-148) --14 + j*(-153) --68 + j*(-142) --179 + j*(-107) --211 + j*(71) --58 + j*(149) --26 + j*(57) --117 + j*(155) -84 + j*(344) -407 + j*(170) -378 + j*(-184) -158 + j*(-296) -35 + j*(-284) --87 + j*(-274) --168 + j*(-157) --114 + j*(-103) --168 + j*(-168) --328 + j*(-48) --250 + j*(185) --42 + j*(190) --8 + j*(85) --21 + j*(76) --8 + j*(45) --76 + j*(54) --27 + j*(190) -190 + j*(132) -170 + j*(-142) --105 + j*(-183) --204 + j*(33) --92 + j*(165) -28 + j*(173) -127 + j*(103) -102 + j*(-33) --23 + j*(-9) -51 + j*(109) -190 + j*(-38) --11 + j*(-218) --225 + j*(-1) --25 + j*(212) -148 + j*(43) --7 + j*(-45) -1 + j*(132) -233 + j*(62) -165 + j*(-228) --132 + j*(-211) --180 + j*(21) --56 + j*(96) --8 + j*(82) -44 + j*(94) -104 + j*(25) -35 + j*(-51) --43 + j*(27) -45 + j*(134) -209 + j*(76) -254 + j*(-117) -107 + j*(-292) --150 + j*(-268) --263 + j*(-11) --60 + j*(197) -191 + j*(55) -93 + j*(-218) --197 + j*(-148) --148 + j*(162) -184 + j*(128) -178 + j*(-226) --180 + j*(-267) --271 + j*(51) --34 + j*(158) -41 + j*(13) --38 + j*(0) -1 + j*(40) -6 + j*(-18) --59 + j*(40) -88 + j*(136) -261 + j*(-80) -59 + j*(-350) --248 + j*(-250) --266 + j*(-21) --182 + j*(36) --177 + j*(53) --161 + j*(85) --193 + j*(107) --207 + j*(268) -27 + j*(402) -247 + j*(209) -129 + j*(17) -56 + j*(136) -258 + j*(120) -229 + j*(-168) --78 + j*(-160) --64 + j*(113) -170 + j*(59) -77 + j*(-148) --108 + j*(-31) -15 + j*(130) -151 + j*(8) -51 + j*(-105) --40 + j*(-45) --42 + j*(8) --46 + j*(79) -69 + j*(174) -252 + j*(73) -219 + j*(-144) -48 + j*(-170) -27 + j*(-79) -76 + j*(-110) -14 + j*(-173) --57 + j*(-125) --37 + j*(-83) --28 + j*(-112) --76 + j*(-127) --127 + j*(-107) --182 + j*(-55) --190 + j*(67) --52 + j*(153) -88 + j*(37) --12 + j*(-134) --209 + j*(-48) --156 + j*(166) -36 + j*(158) -42 + j*(40) -16 + j*(83) -163 + j*(47) -121 + j*(-222) --246 + j*(-230) --334 + j*(179) -50 + j*(338) -243 + j*(25) -16 + j*(-159) --142 + j*(-8) --72 + j*(122) -25 + j*(144) -138 + j*(94) -143 + j*(-86) --79 + j*(-124) --121 + j*(132) -185 + j*(173) -239 + j*(-182) --132 + j*(-284) --294 + j*(43) --78 + j*(240) -91 + j*(185) -195 + j*(122) -308 + j*(-75) -124 + j*(-369) --279 + j*(-296) --353 + j*(95) --79 + j*(262) -76 + j*(132) -30 + j*(67) -55 + j*(129) -194 + j*(81) -192 + j*(-132) --52 + j*(-206) --191 + j*(40) -42 + j*(218) -232 + j*(6) -36 + j*(-152) --55 + j*(59) -214 + j*(88) -226 + j*(-250) --139 + j*(-286) --190 + j*(41) -70 + j*(71) -55 + j*(-124) --89 + j*(-54) -37 + j*(49) -132 + j*(-125) --43 + j*(-244) --177 + j*(-129) --149 + j*(-38) --137 + j*(-24) --142 + j*(4) --150 + j*(25) --171 + j*(105) --52 + j*(214) -131 + j*(100) -37 + j*(-120) --204 + j*(-43) --158 + j*(200) -51 + j*(194) -59 + j*(61) -1 + j*(87) -82 + j*(112) -108 + j*(1) --3 + j*(-28) --23 + j*(77) -76 + j*(83) -66 + j*(-2) --14 + j*(46) -72 + j*(158) -244 + j*(79) -236 + j*(-113) -114 + j*(-178) -60 + j*(-178) --21 + j*(-221) --165 + j*(-146) --140 + j*(19) --21 + j*(2) --102 + j*(-72) --185 + j*(98) -42 + j*(233) -225 + j*(3) -28 + j*(-192) --140 + j*(-33) --7 + j*(78) -38 + j*(-54) --113 + j*(-42) --71 + j*(146) -151 + j*(107) -143 + j*(-125) --66 + j*(-162) --119 + j*(-9) --29 + j*(5) --102 + j*(-79) --268 + j*(76) --108 + j*(378) -293 + j*(308) -334 + j*(-91) -11 + j*(-167) -0 + j*(102) -304 + j*(29) -221 + j*(-356) --197 + j*(-358) --294 + j*(-16) --108 + j*(108) --43 + j*(82) -37 + j*(127) -197 + j*(-4) -68 + j*(-255) --235 + j*(-165) --197 + j*(137) -63 + j*(132) -61 + j*(-66) --91 + j*(-42) --37 + j*(91) -100 + j*(26) -60 + j*(-134) --96 + j*(-156) --182 + j*(-64) --192 + j*(13) --215 + j*(84) --202 + j*(231) --19 + j*(366) -247 + j*(267) -278 + j*(-31) -21 + j*(-142) --112 + j*(76) -100 + j*(225) -283 + j*(19) -115 + j*(-186) --77 + j*(-58) -45 + j*(105) -199 + j*(-28) -84 + j*(-192) --70 + j*(-128) --62 + j*(-35) --59 + j*(-8) --18 + j*(86) -176 + j*(46) -160 + j*(-254) --221 + j*(-291) --323 + j*(122) -72 + j*(262) -206 + j*(-103) --147 + j*(-211) --238 + j*(141) -100 + j*(235) -200 + j*(-59) --37 + j*(-152) --114 + j*(34) -33 + j*(107) -126 + j*(5) -100 + j*(-115) --15 + j*(-191) --179 + j*(-140) --224 + j*(51) --86 + j*(173) -54 + j*(123) -80 + j*(24) -42 + j*(-43) --30 + j*(-70) --118 + j*(-21) --136 + j*(110) --18 + j*(228) -181 + j*(202) -283 + j*(4) -170 + j*(-181) -2 + j*(-163) --1 + j*(-71) -43 + j*(-122) --56 + j*(-192) --161 + j*(-115) --156 + j*(-45) --197 + j*(-29) --255 + j*(115) --100 + j*(283) -112 + j*(202) -103 + j*(40) -40 + j*(46) -104 + j*(28) -45 + j*(-110) --158 + j*(-43) --114 + j*(212) -162 + j*(218) -224 + j*(-30) -39 + j*(-115) --30 + j*(13) -65 + j*(57) -101 + j*(-19) -54 + j*(-53) -42 + j*(-27) -81 + j*(-44) -65 + j*(-117) --36 + j*(-137) --88 + j*(-47) --27 + j*(-2) --19 + j*(-59) --105 + j*(-21) --44 + j*(110) -124 + j*(50) -86 + j*(-128) --64 + j*(-110) --41 + j*(-31) --33 + j*(-107) --197 + j*(-87) --207 + j*(129) --13 + j*(190) -45 + j*(83) -28 + j*(101) -155 + j*(90) -182 + j*(-108) --11 + j*(-187) --96 + j*(-67) --54 + j*(-40) --118 + j*(-52) --151 + j*(76) --30 + j*(140) -28 + j*(68) --1 + j*(66) -59 + j*(91) -106 + j*(13) -63 + j*(-46) -30 + j*(-65) --52 + j*(-95) --160 + j*(30) --26 + j*(209) -195 + j*(98) -116 + j*(-109) --30 + j*(-35) -85 + j*(37) -122 + j*(-138) --80 + j*(-183) --139 + j*(-16) --52 + j*(21) --83 + j*(8) --54 + j*(124) -121 + j*(78) -69 + j*(-126) --141 + j*(-68) --84 + j*(131) -74 + j*(79) -15 + j*(-7) -12 + j*(95) -184 + j*(45) -122 + j*(-194) --146 + j*(-146) --102 + j*(121) -168 + j*(62) -98 + j*(-232) --227 + j*(-185) --233 + j*(142) -51 + j*(192) -104 + j*(-26) --62 + j*(-37) --11 + j*(115) -159 + j*(13) -35 + j*(-194) --204 + j*(-81) --124 + j*(170) -105 + j*(130) -91 + j*(-57) --46 + j*(-47) --34 + j*(46) -18 + j*(25) --19 + j*(13) --1 + j*(90) -125 + j*(73) -142 + j*(-82) --7 + j*(-134) --57 + j*(-12) -56 + j*(1) -25 + j*(-146) --174 + j*(-100) --139 + j*(134) -93 + j*(115) -64 + j*(-90) --108 + j*(-28) --1 + j*(120) -132 + j*(-34) --59 + j*(-165) --207 + j*(35) --47 + j*(202) -100 + j*(136) -141 + j*(77) -220 + j*(-18) -155 + j*(-210) --57 + j*(-214) --86 + j*(-76) --43 + j*(-117) --204 + j*(-126) --249 + j*(128) -28 + j*(229) -165 + j*(-16) --25 + j*(-170) --192 + j*(-66) --209 + j*(88) --129 + j*(233) -81 + j*(271) -209 + j*(80) -72 + j*(-46) -18 + j*(77) -187 + j*(63) -157 + j*(-168) --95 + j*(-155) --91 + j*(73) -98 + j*(53) -54 + j*(-110) --90 + j*(-47) --23 + j*(76) -80 + j*(1) -1 + j*(-93) --100 + j*(-33) --98 + j*(78) --21 + j*(166) -151 + j*(190) -321 + j*(1) -203 + j*(-288) --123 + j*(-281) --194 + j*(-1) -13 + j*(88) -78 + j*(-65) --23 + j*(-102) --22 + j*(-69) --57 + j*(-141) --228 + j*(-72) --181 + j*(177) -86 + j*(182) -119 + j*(-33) -4 + j*(-56) -50 + j*(-43) --4 + j*(-202) --270 + j*(-153) --286 + j*(146) --64 + j*(211) --37 + j*(127) --25 + j*(225) -196 + j*(214) -241 + j*(-38) -58 + j*(-103) -51 + j*(-18) -80 + j*(-117) --96 + j*(-141) --125 + j*(45) -23 + j*(34) --79 + j*(-83) --216 + j*(120) -38 + j*(322) -293 + j*(91) -132 + j*(-173) --103 + j*(-79) --69 + j*(127) -124 + j*(176) -286 + j*(19) -222 + j*(-245) --86 + j*(-308) --252 + j*(-31) --45 + j*(192) -200 + j*(66) -170 + j*(-175) --29 + j*(-252) --189 + j*(-151) --204 + j*(22) --84 + j*(115) -18 + j*(67) -18 + j*(1) --2 + j*(-13) --11 + j*(-31) --57 + j*(-40) --103 + j*(17) --69 + j*(106) -46 + j*(123) -122 + j*(16) -49 + j*(-89) --46 + j*(-57) --28 + j*(-10) --50 + j*(-45) --136 + j*(37) --18 + j*(188) -182 + j*(63) -70 + j*(-157) --140 + j*(-64) --78 + j*(111) -35 + j*(95) -66 + j*(81) -185 + j*(32) -162 + j*(-202) --117 + j*(-233) --161 + j*(8) -6 + j*(-26) --165 + j*(-170) --362 + j*(101) --98 + j*(355) -115 + j*(180) --6 + j*(114) -75 + j*(283) -329 + j*(164) -286 + j*(-95) -141 + j*(-126) -104 + j*(-136) --6 + j*(-132) -7 + j*(22) -205 + j*(-46) -93 + j*(-307) --196 + j*(-183) --59 + j*(74) -151 + j*(-113) --83 + j*(-315) --296 + j*(-106) --171 + j*(77) --71 + j*(35) --72 + j*(4) --87 + j*(-40) --209 + j*(-25) --231 + j*(175) --37 + j*(239) --9 + j*(131) --40 + j*(248) -265 + j*(286) -378 + j*(-141) --78 + j*(-327) --289 + j*(93) -57 + j*(281) -181 + j*(31) -14 + j*(23) -139 + j*(173) -344 + j*(-11) -225 + j*(-270) -10 + j*(-289) --103 + j*(-218) --167 + j*(-113) --125 + j*(-10) --69 + j*(-30) --124 + j*(-33) --103 + j*(62) -4 + j*(15) --92 + j*(-112) --288 + j*(6) --251 + j*(276) -4 + j*(411) -286 + j*(305) -386 + j*(-4) -161 + j*(-228) --64 + j*(-95) -54 + j*(63) -171 + j*(-109) --41 + j*(-246) --227 + j*(-56) --119 + j*(155) -76 + j*(156) -170 + j*(5) -58 + j*(-159) --158 + j*(-61) --49 + j*(208) -276 + j*(100) -196 + j*(-252) --112 + j*(-204) --63 + j*(-6) -14 + j*(-114) --177 + j*(-100) --102 + j*(158) -188 + j*(33) -34 + j*(-267) --239 + j*(-119) --108 + j*(65) --68 + j*(-85) --296 + j*(1) --157 + j*(327) -224 + j*(201) -135 + j*(-182) --231 + j*(-141) --275 + j*(192) --20 + j*(354) -240 + j*(245) -291 + j*(-37) -54 + j*(-195) --135 + j*(-11) -25 + j*(170) -205 + j*(23) -100 + j*(-162) --71 + j*(-133) --131 + j*(-20) --115 + j*(113) -40 + j*(216) -250 + j*(104) -235 + j*(-154) -15 + j*(-248) --147 + j*(-132) --148 + j*(35) --17 + j*(121) -110 + j*(30) -44 + j*(-112) --106 + j*(-56) --55 + j*(97) -101 + j*(49) -62 + j*(-112) --109 + j*(-88) --120 + j*(91) -51 + j*(150) -152 + j*(11) -57 + j*(-103) --35 + j*(-41) -23 + j*(16) -52 + j*(-61) --41 + j*(-70) --28 + j*(37) -96 + j*(8) -76 + j*(-127) --33 + j*(-134) --47 + j*(-99) --90 + j*(-128) --177 + j*(-52) --112 + j*(59) --25 + j*(-8) --124 + j*(-69) --187 + j*(62) --61 + j*(129) --21 + j*(21) --146 + j*(18) --155 + j*(183) -16 + j*(247) -124 + j*(129) -52 + j*(31) --17 + j*(124) -143 + j*(221) -337 + j*(25) -185 + j*(-251) --93 + j*(-180) --52 + j*(13) -37 + j*(-83) --168 + j*(-117) --214 + j*(187) -127 + j*(282) -261 + j*(-25) -44 + j*(-146) --10 + j*(-31) -24 + j*(-95) --183 + j*(-95) --222 + j*(240) -168 + j*(390) -433 + j*(71) -298 + j*(-221) -113 + j*(-276) --38 + j*(-285) --211 + j*(-148) --129 + j*(102) -140 + j*(42) -71 + j*(-243) --246 + j*(-169) --197 + j*(172) -141 + j*(163) -176 + j*(-131) --39 + j*(-188) --71 + j*(-68) --6 + j*(-113) --122 + j*(-194) --250 + j*(-72) --182 + j*(49) --130 + j*(2) --233 + j*(1) --279 + j*(167) --152 + j*(306) -4 + j*(311) -115 + j*(258) -196 + j*(161) -183 + j*(35) -96 + j*(2) -91 + j*(52) -163 + j*(17) -135 + j*(-98) -13 + j*(-98) -6 + j*(10) -126 + j*(-1) -124 + j*(-168) --72 + j*(-218) --180 + j*(-43) --50 + j*(76) -38 + j*(-34) --102 + j*(-103) --193 + j*(77) --8 + j*(222) -180 + j*(76) -91 + j*(-114) --70 + j*(-62) --25 + j*(64) -83 + j*(8) -17 + j*(-104) --108 + j*(-43) --68 + j*(95) -66 + j*(85) -87 + j*(-28) -7 + j*(-65) --32 + j*(-13) -8 + j*(21) -50 + j*(-14) -21 + j*(-77) --58 + j*(-66) --64 + j*(24) -18 + j*(32) -10 + j*(-45) --84 + j*(0) --7 + j*(138) -182 + j*(66) -154 + j*(-149) --35 + j*(-161) --43 + j*(-35) -289 + j*(-105) -48 + j*(-267) --117 + j*(-80) -29 + j*(9) -35 + j*(-146) --147 + j*(-115) --127 + j*(57) --21 + j*(53) --33 + j*(38) -35 + j*(74) -91 + j*(-54) --83 + j*(-115) --143 + j*(86) -59 + j*(139) -90 + j*(-30) --27 + j*(-8) -72 + j*(67) -134 + j*(-110) --86 + j*(-178) --147 + j*(43) -63 + j*(65) -36 + j*(-163) --241 + j*(-127) --261 + j*(175) --10 + j*(271) -105 + j*(127) -33 + j*(82) -76 + j*(185) -282 + j*(139) -342 + j*(-134) -117 + j*(-313) --91 + j*(-217) --93 + j*(-85) --62 + j*(-66) --66 + j*(-48) --45 + j*(-54) --103 + j*(-93) --198 + j*(10) --96 + j*(158) -62 + j*(83) --5 + j*(-36) --83 + j*(56) -40 + j*(118) -115 + j*(-21) --5 + j*(-117) --124 + j*(-46) --124 + j*(76) --24 + j*(152) -101 + j*(85) -59 + j*(-54) --82 + j*(-16) --40 + j*(128) -96 + j*(98) -89 + j*(8) -78 + j*(14) -117 + j*(-49) -11 + j*(-134) --95 + j*(-16) -24 + j*(91) -124 + j*(-26) -34 + j*(-121) --38 + j*(-86) --65 + j*(-70) --132 + j*(-6) --73 + j*(136) -105 + j*(129) -165 + j*(-20) -114 + j*(-127) -27 + j*(-206) --149 + j*(-214) --279 + j*(-35) --199 + j*(165) --30 + j*(222) -127 + j*(180) -237 + j*(3) -117 + j*(-216) --130 + j*(-172) --134 + j*(24) --23 + j*(24) --66 + j*(-16) --55 + j*(66) -30 + j*(5) --110 + j*(-68) --191 + j*(171) -123 + j*(295) -298 + j*(-30) -11 + j*(-223) --153 + j*(-2) -4 + j*(105) -43 + j*(1) --23 + j*(31) -62 + j*(81) -114 + j*(-18) -42 + j*(-70) -21 + j*(-55) --17 + j*(-88) --118 + j*(-25) --51 + j*(135) -152 + j*(98) -173 + j*(-116) --1 + j*(-206) --134 + j*(-121) --135 + j*(-4) --72 + j*(30) --74 + j*(0) --143 + j*(57) --77 + j*(211) -144 + j*(200) -202 + j*(-10) -59 + j*(-81) -58 + j*(10) -178 + j*(-93) -22 + j*(-322) --337 + j*(-206) --330 + j*(221) -78 + j*(327) -239 + j*(-14) --35 + j*(-155) --123 + j*(98) -151 + j*(136) -168 + j*(-165) --141 + j*(-185) --166 + j*(93) -47 + j*(113) -43 + j*(-6) -30 + j*(49) -165 + j*(-33) -17 + j*(-255) --269 + j*(-81) --86 + j*(231) -225 + j*(40) -30 + j*(-259) --252 + j*(-91) --139 + j*(146) -13 + j*(98) -14 + j*(58) -77 + j*(35) -42 + j*(-102) --147 + j*(-42) --55 + j*(191) -230 + j*(76) -115 + j*(-262) --256 + j*(-185) --249 + j*(168) -25 + j*(216) -93 + j*(48) -23 + j*(21) -58 + j*(40) -56 + j*(-28) --37 + j*(-1) -32 + j*(119) -198 + j*(11) -76 + j*(-219) --213 + j*(-105) --132 + j*(235) -230 + j*(217) -286 + j*(-113) -52 + j*(-210) --11 + j*(-78) -75 + j*(-99) --7 + j*(-212) --186 + j*(-150) --212 + j*(49) --55 + j*(184) -151 + j*(121) -186 + j*(-97) -4 + j*(-198) --103 + j*(-67) -1 + j*(5) -44 + j*(-101) --55 + j*(-142) --87 + j*(-94) --101 + j*(-129) --243 + j*(-112) --301 + j*(93) --132 + j*(234) -18 + j*(151) --12 + j*(62) --49 + j*(107) -35 + j*(147) -117 + j*(44) -16 + j*(-88) --175 + j*(0) --128 + j*(248) -146 + j*(272) -226 + j*(30) -36 + j*(-52) --14 + j*(125) -177 + j*(180) -288 + j*(15) -226 + j*(-129) -146 + j*(-189) -43 + j*(-238) --108 + j*(-192) --154 + j*(-26) --35 + j*(66) -40 + j*(-11) --47 + j*(-35) --35 + j*(124) -231 + j*(130) -330 + j*(-210) -6 + j*(-432) --267 + j*(-223) --188 + j*(-30) --155 + j*(-62) --239 + j*(41) --90 + j*(183) -37 + j*(34) --144 + j*(-7) --110 + j*(267) -263 + j*(215) -240 + j*(-197) --127 + j*(-203) --124 + j*(60) -16 + j*(-4) --152 + j*(-30) --110 + j*(262) -289 + j*(213) -280 + j*(-238) --146 + j*(-282) --222 + j*(64) -23 + j*(141) -82 + j*(-6) -25 + j*(-49) -6 + j*(-81) --108 + j*(-105) --194 + j*(47) --64 + j*(187) -83 + j*(114) -59 + j*(8) -0 + j*(14) --1 + j*(57) -37 + j*(90) -122 + j*(75) -168 + j*(-39) -73 + j*(-146) --55 + j*(-95) --36 + j*(14) -54 + j*(-6) -14 + j*(-96) --99 + j*(-51) --68 + j*(88) -85 + j*(91) -134 + j*(-51) -41 + j*(-154) --95 + j*(-151) --206 + j*(-25) --144 + j*(183) -107 + j*(202) -188 + j*(-37) --20 + j*(-119) --62 + j*(71) -147 + j*(68) -124 + j*(-173) --122 + j*(-161) --127 + j*(53) -21 + j*(59) -6 + j*(-20) --13 + j*(25) -59 + j*(1) -4 + j*(-86) --95 + j*(-6) -8 + j*(105) -144 + j*(-4) -68 + j*(-172) --110 + j*(-169) --196 + j*(-29) --133 + j*(106) --3 + j*(113) -34 + j*(15) --41 + j*(-21) --91 + j*(33) --90 + j*(110) --18 + j*(216) -197 + j*(218) -314 + j*(-42) -87 + j*(-242) --115 + j*(-71) -33 + j*(80) -140 + j*(-82) --29 + j*(-170) --99 + j*(-30) --1 + j*(-6) --40 + j*(-76) --98 + j*(8) -1 + j*(52) -15 + j*(-54) --93 + j*(-42) --65 + j*(50) --20 + j*(-1) --129 + j*(8) --103 + j*(194) -134 + j*(193) -154 + j*(-35) --39 + j*(-37) -11 + j*(146) -216 + j*(68) -156 + j*(-149) --17 + j*(-116) -37 + j*(-21) -90 + j*(-150) --112 + j*(-232) --263 + j*(-30) --138 + j*(153) -8 + j*(112) --6 + j*(47) --35 + j*(86) -14 + j*(156) -151 + j*(177) -316 + j*(31) -255 + j*(-251) --49 + j*(-311) --167 + j*(-69) -13 + j*(4) -6 + j*(-192) --267 + j*(-154) --273 + j*(182) -54 + j*(267) -185 + j*(0) --18 + j*(-135) --144 + j*(32) -2 + j*(172) -166 + j*(59) -109 + j*(-117) --37 + j*(-109) --45 + j*(-27) --28 + j*(-60) --139 + j*(-47) --143 + j*(141) -78 + j*(190) -168 + j*(-18) -1 + j*(-113) --71 + j*(6) -6 + j*(42) -5 + j*(3) --3 + j*(49) -91 + j*(45) -108 + j*(-82) --16 + j*(-148) --133 + j*(-73) --136 + j*(76) -23 + j*(173) -211 + j*(23) -102 + j*(-249) --216 + j*(-225) --303 + j*(62) --138 + j*(218) --2 + j*(214) -100 + j*(173) -144 + j*(47) -25 + j*(-8) -6 + j*(151) -246 + j*(177) -357 + j*(-109) -131 + j*(-318) --112 + j*(-233) --158 + j*(-30) --19 + j*(103) -180 + j*(0) -107 + j*(-271) --215 + j*(-262) --282 + j*(39) --81 + j*(137) --29 + j*(65) -1 + j*(115) -158 + j*(27) -47 + j*(-217) --241 + j*(-107) --150 + j*(170) -54 + j*(88) --59 + j*(-16) --83 + j*(154) -124 + j*(134) -70 + j*(-66) --105 + j*(45) -65 + j*(219) -265 + j*(42) -152 + j*(-168) --22 + j*(-149) --83 + j*(-40) --25 + j*(85) -170 + j*(56) -179 + j*(-217) --138 + j*(-293) --273 + j*(-1) --75 + j*(133) --13 + j*(32) --70 + j*(78) -46 + j*(151) -146 + j*(57) -153 + j*(-16) -195 + j*(-137) -28 + j*(-334) --276 + j*(-197) --188 + j*(105) -34 + j*(-1) --150 + j*(-147) --267 + j*(112) -5 + j*(197) -16 + j*(-44) --216 + j*(57) --28 + j*(312) -238 + j*(98) -31 + j*(-144) --156 + j*(45) --7 + j*(180) -56 + j*(98) -30 + j*(136) -173 + j*(168) -258 + j*(-6) -145 + j*(-132) -42 + j*(-111) -1 + j*(-65) -16 + j*(-4) -90 + j*(-25) -50 + j*(-115) --30 + j*(-59) -59 + j*(-30) -15 + j*(-192) --250 + j*(-86) --112 + j*(277) -327 + j*(137) -206 + j*(-332) --237 + j*(-243) --171 + j*(117) -79 + j*(52) --7 + j*(-91) --53 + j*(17) -75 + j*(-9) -6 + j*(-153) --129 + j*(-91) --99 + j*(-10) --106 + j*(-25) --136 + j*(52) --40 + j*(88) --48 + j*(1) --161 + j*(84) --45 + j*(264) -179 + j*(209) -245 + j*(39) -233 + j*(-105) -105 + j*(-275) --171 + j*(-233) --192 + j*(54) -74 + j*(65) -41 + j*(-211) --262 + j*(-182) --293 + j*(94) --141 + j*(161) --134 + j*(158) --73 + j*(276) -132 + j*(254) -175 + j*(54) -16 + j*(-18) --84 + j*(126) -39 + j*(310) -330 + j*(296) -501 + j*(-6) -334 + j*(-305) -71 + j*(-325) --45 + j*(-229) --115 + j*(-142) --98 + j*(11) -86 + j*(33) -119 + j*(-179) --106 + j*(-235) --180 + j*(-46) --73 + j*(-6) --128 + j*(-57) --189 + j*(103) -11 + j*(227) -194 + j*(70) -141 + j*(-124) --1 + j*(-195) --173 + j*(-159) --265 + j*(54) --91 + j*(255) -147 + j*(177) -175 + j*(-4) -122 + j*(-93) -39 + j*(-185) --155 + j*(-162) --191 + j*(64) -11 + j*(116) -21 + j*(-49) --126 + j*(13) --3 + j*(163) -136 + j*(6) --46 + j*(-89) --78 + j*(132) -209 + j*(125) -206 + j*(-209) --115 + j*(-246) --169 + j*(-5) --25 + j*(13) --78 + j*(-70) --147 + j*(35) --38 + j*(98) --1 + j*(-1) --103 + j*(-11) --120 + j*(90) --57 + j*(137) --13 + j*(147) -47 + j*(153) -107 + j*(101) -100 + j*(24) -37 + j*(-1) --18 + j*(52) -26 + j*(156) -185 + j*(162) -270 + j*(-8) -148 + j*(-137) -51 + j*(-60) -148 + j*(-20) -189 + j*(-180) -4 + j*(-284) --164 + j*(-153) --118 + j*(13) -3 + j*(23) -24 + j*(-56) --43 + j*(-78) --88 + j*(-6) --18 + j*(78) -110 + j*(32) -114 + j*(-117) --15 + j*(-175) --87 + j*(-96) --46 + j*(-64) --71 + j*(-127) --206 + j*(-91) --226 + j*(105) --23 + j*(203) -134 + j*(45) -30 + j*(-124) --115 + j*(-62) --65 + j*(28) --31 + j*(-54) --179 + j*(-63) --210 + j*(136) --16 + j*(198) -36 + j*(40) --106 + j*(38) --68 + j*(192) -78 + j*(156) -47 + j*(64) -39 + j*(136) -185 + j*(86) -110 + j*(-131) --153 + j*(-52) --91 + j*(232) -165 + j*(208) -156 + j*(53) -134 + j*(125) -352 + j*(78) -346 + j*(-262) --13 + j*(-349) --147 + j*(-60) -64 + j*(48) -127 + j*(-127) --36 + j*(-159) --47 + j*(2) -148 + j*(4) -195 + j*(-245) --71 + j*(-416) --358 + j*(-235) --324 + j*(68) --119 + j*(122) --91 + j*(37) --129 + j*(89) --40 + j*(146) -21 + j*(93) -28 + j*(99) -151 + j*(76) -176 + j*(-152) --89 + j*(-262) --268 + j*(-39) --136 + j*(136) --42 + j*(90) --69 + j*(110) -40 + j*(185) -185 + j*(63) -122 + j*(-134) --73 + j*(-173) --218 + j*(-44) --208 + j*(163) --20 + j*(275) -141 + j*(173) -112 + j*(64) -101 + j*(95) -206 + j*(52) -184 + j*(-124) --6 + j*(-166) --108 + j*(-8) --1 + j*(148) -205 + j*(106) -245 + j*(-127) -27 + j*(-231) --72 + j*(-45) -124 + j*(-6) -107 + j*(-274) --233 + j*(-255) --246 + j*(96) -51 + j*(117) -33 + j*(-96) --96 + j*(-16) -52 + j*(31) -20 + j*(-190) --269 + j*(-102) --158 + j*(219) -146 + j*(103) -16 + j*(-148) --162 + j*(-1) --6 + j*(86) --26 + j*(-93) --250 + j*(21) --105 + j*(300) -186 + j*(184) -116 + j*(-55) --38 + j*(-11) --4 + j*(71) -16 + j*(56) -22 + j*(95) -110 + j*(95) -133 + j*(8) -105 + j*(-18) -121 + j*(-63) -32 + j*(-133) --62 + j*(-13) -107 + j*(81) -227 + j*(-165) --63 + j*(-356) --326 + j*(-103) --173 + j*(166) -21 + j*(103) --13 + j*(16) --28 + j*(69) -35 + j*(64) -17 + j*(31) -24 + j*(100) -172 + j*(95) -235 + j*(-98) -76 + j*(-238) --76 + j*(-169) --74 + j*(-90) --94 + j*(-104) --181 + j*(-21) --91 + j*(144) -133 + j*(70) -83 + j*(-201) --218 + j*(-201) --285 + j*(86) --70 + j*(182) --14 + j*(47) --133 + j*(74) --64 + j*(236) -134 + j*(196) -145 + j*(21) -33 + j*(-3) -31 + j*(71) -93 + j*(63) -103 + j*(27) -136 + j*(8) -159 + j*(-101) -6 + j*(-204) --166 + j*(-51) --32 + j*(163) -197 + j*(45) -89 + j*(-181) --113 + j*(-66) -34 + j*(115) -224 + j*(-70) -40 + j*(-300) --203 + j*(-174) --153 + j*(20) --46 + j*(-1) --86 + j*(-54) --144 + j*(-4) --142 + j*(78) --77 + j*(152) -35 + j*(143) -64 + j*(58) -30 + j*(57) -103 + j*(73) -147 + j*(-69) --13 + j*(-156) --113 + j*(-19) --8 + j*(49) -1 + j*(-51) --122 + j*(-18) --88 + j*(131) -46 + j*(125) -52 + j*(45) -18 + j*(74) -99 + j*(122) -229 + j*(40) -226 + j*(-179) --26 + j*(-305) --270 + j*(-82) --103 + j*(228) -225 + j*(115) -159 + j*(-190) --81 + j*(-153) --35 + j*(-6) -34 + j*(-107) --125 + j*(-144) --168 + j*(22) --47 + j*(45) --95 + j*(-20) --159 + j*(114) -14 + j*(233) -197 + j*(102) -174 + j*(-106) --4 + j*(-222) --247 + j*(-124) --266 + j*(206) -88 + j*(342) -296 + j*(18) -17 + j*(-190) --146 + j*(75) -149 + j*(204) -288 + j*(-123) --25 + j*(-312) --264 + j*(-69) --137 + j*(181) -74 + j*(180) -169 + j*(55) -150 + j*(-76) -47 + j*(-137) --26 + j*(-86) -4 + j*(-62) --24 + j*(-129) --163 + j*(-97) --177 + j*(95) -24 + j*(166) -134 + j*(-13) --17 + j*(-141) --153 + j*(-25) --85 + j*(95) --29 + j*(76) --37 + j*(125) -110 + j*(194) -278 + j*(7) -135 + j*(-240) --113 + j*(-179) --115 + j*(-4) --42 + j*(2) --67 + j*(11) --9 + j*(69) -59 + j*(-32) --93 + j*(-112) --205 + j*(74) --33 + j*(229) -126 + j*(125) -100 + j*(23) -87 + j*(9) -70 + j*(-52) --30 + j*(-29) -18 + j*(99) -185 + j*(21) -101 + j*(-180) --99 + j*(-108) --31 + j*(54) -78 + j*(-33) --46 + j*(-89) --52 + j*(81) -185 + j*(49) -157 + j*(-255) --177 + j*(-282) --271 + j*(8) --87 + j*(125) --6 + j*(40) --25 + j*(14) --21 + j*(-10) --103 + j*(-24) --145 + j*(128) -56 + j*(224) -201 + j*(26) -47 + j*(-132) --82 + j*(-22) --1 + j*(52) -16 + j*(-13) --42 + j*(16) -16 + j*(66) -49 + j*(-5) --40 + j*(-9) --18 + j*(112) -144 + j*(107) -204 + j*(-70) -72 + j*(-212) --123 + j*(-176) --181 + j*(23) --6 + j*(134) -121 + j*(-31) --50 + j*(-162) --195 + j*(7) --65 + j*(153) -37 + j*(91) -40 + j*(92) -170 + j*(61) -163 + j*(-193) --170 + j*(-240) --288 + j*(107) --1 + j*(282) -185 + j*(114) -162 + j*(-13) -153 + j*(-107) --3 + j*(-224) --206 + j*(-63) --57 + j*(169) -165 + j*(22) -11 + j*(-170) --147 + j*(-13) -1 + j*(107) -85 + j*(-23) --13 + j*(-83) --57 + j*(-38) --77 + j*(-19) --95 + j*(47) --35 + j*(86) --41 + j*(71) --32 + j*(205) -263 + j*(254) -446 + j*(-144) -64 + j*(-469) --317 + j*(-196) --170 + j*(134) -43 + j*(57) --21 + j*(-52) --77 + j*(8) --59 + j*(57) --23 + j*(123) -140 + j*(134) -221 + j*(-90) --5 + j*(-235) --171 + j*(-45) --26 + j*(109) -98 + j*(6) -53 + j*(-85) -20 + j*(-107) --38 + j*(-162) --164 + j*(-141) --222 + j*(-29) --217 + j*(60) --197 + j*(170) --65 + j*(260) -76 + j*(199) -81 + j*(114) -95 + j*(112) -139 + j*(42) -67 + j*(-21) -35 + j*(58) -151 + j*(43) -117 + j*(-108) --39 + j*(-65) -33 + j*(71) -153 + j*(-46) -3 + j*(-164) --120 + j*(-2) -28 + j*(127) -170 + j*(25) -165 + j*(-112) -88 + j*(-227) --107 + j*(-260) --238 + j*(-64) --82 + j*(87) -16 + j*(-58) --175 + j*(-95) --187 + j*(146) -65 + j*(148) -33 + j*(-88) --204 + j*(-8) --112 + j*(245) -112 + j*(188) -80 + j*(72) -94 + j*(163) -308 + j*(91) -301 + j*(-218) -12 + j*(-330) --177 + j*(-164) --170 + j*(13) --62 + j*(122) -107 + j*(92) -132 + j*(-90) --40 + j*(-125) --41 + j*(42) -165 + j*(-6) -113 + j*(-285) --213 + j*(-308) --335 + j*(-26) --180 + j*(148) --30 + j*(113) -8 + j*(11) --77 + j*(-79) --247 + j*(-12) --247 + j*(233) --6 + j*(336) -141 + j*(191) -93 + j*(113) -146 + j*(161) -292 + j*(35) -192 + j*(-216) --88 + j*(-197) --121 + j*(41) -64 + j*(60) -31 + j*(-109) --173 + j*(-31) --81 + j*(224) -200 + j*(147) -132 + j*(-132) --136 + j*(-41) --18 + j*(240) -288 + j*(127) -226 + j*(-165) -8 + j*(-162) --4 + j*(-52) -6 + j*(-53) --10 + j*(20) -144 + j*(53) -215 + j*(-162) -6 + j*(-276) --84 + j*(-134) -16 + j*(-155) --129 + j*(-308) --391 + j*(-144) --329 + j*(155) --134 + j*(208) --63 + j*(195) -69 + j*(210) -174 + j*(31) --1 + j*(-110) --136 + j*(81) -98 + j*(218) -280 + j*(-43) -37 + j*(-285) --244 + j*(-103) --130 + j*(182) -132 + j*(116) -78 + j*(-113) --134 + j*(-38) --12 + j*(190) -277 + j*(32) -137 + j*(-336) --269 + j*(-279) --306 + j*(73) --84 + j*(141) --79 + j*(33) --160 + j*(114) --60 + j*(229) -64 + j*(197) -116 + j*(135) -141 + j*(62) -92 + j*(-4) -40 + j*(38) -105 + j*(69) -138 + j*(-11) -86 + j*(-39) -103 + j*(-30) -90 + j*(-114) --45 + j*(-99) --21 + j*(61) -155 + j*(28) -143 + j*(-152) -14 + j*(-182) --38 + j*(-177) --177 + j*(-168) --257 + j*(71) -22 + j*(226) -203 + j*(-59) --80 + j*(-229) --218 + j*(40) -30 + j*(115) -11 + j*(-123) --260 + j*(-18) --127 + j*(306) -204 + j*(222) -184 + j*(-29) -74 + j*(-21) -145 + j*(-28) -97 + j*(-173) --65 + j*(-141) --32 + j*(-24) -42 + j*(-103) --76 + j*(-190) --200 + j*(-114) --247 + j*(-19) --295 + j*(141) --132 + j*(388) -254 + j*(333) -330 + j*(-62) -25 + j*(-201) --71 + j*(1) -73 + j*(-6) --41 + j*(-155) --235 + j*(30) --35 + j*(269) -218 + j*(110) -127 + j*(-100) -16 + j*(-71) -24 + j*(-86) --116 + j*(-117) --199 + j*(104) -41 + j*(250) -223 + j*(57) -123 + j*(-101) -54 + j*(-88) -33 + j*(-143) --110 + j*(-144) --150 + j*(2) --69 + j*(37) --112 + j*(37) --70 + j*(188) -166 + j*(158) -164 + j*(-104) --70 + j*(-116) --74 + j*(55) -14 + j*(47) --10 + j*(61) -119 + j*(114) -215 + j*(-118) --82 + j*(-257) --247 + j*(54) -39 + j*(202) -122 + j*(-38) --81 + j*(-23) -25 + j*(167) -210 + j*(18) -73 + j*(-124) -33 + j*(-14) -141 + j*(-105) --53 + j*(-239) --199 + j*(8) -69 + j*(123) -135 + j*(-160) --154 + j*(-180) --127 + j*(86) -100 + j*(2) --37 + j*(-207) --245 + j*(-57) --139 + j*(126) --26 + j*(81) --37 + j*(59) -4 + j*(56) --21 + j*(-15) --119 + j*(55) --18 + j*(194) -148 + j*(102) -82 + j*(-47) --7 + j*(17) -97 + j*(55) -132 + j*(-103) --51 + j*(-179) --177 + j*(-28) --92 + j*(119) -30 + j*(105) -57 + j*(37) -43 + j*(4) -25 + j*(-22) --23 + j*(-17) --28 + j*(54) -62 + j*(68) -92 + j*(-38) --19 + j*(-83) --71 + j*(21) -14 + j*(81) -79 + j*(25) -70 + j*(-34) -31 + j*(-78) --53 + j*(-79) --98 + j*(21) --20 + j*(96) -56 + j*(66) -81 + j*(31) -117 + j*(-33) -43 + j*(-134) --94 + j*(-61) --4 + j*(74) -112 + j*(-68) --100 + j*(-173) --209 + j*(107) -116 + j*(230) -250 + j*(-109) --65 + j*(-243) --179 + j*(18) -12 + j*(88) -21 + j*(-33) --46 + j*(14) -36 + j*(38) -23 + j*(-49) --44 + j*(4) -50 + j*(33) -29 + j*(-98) --134 + j*(-14) -22 + j*(192) -293 + j*(-10) -109 + j*(-337) --204 + j*(-235) --176 + j*(-43) --158 + j*(-93) --324 + j*(-2) --251 + j*(276) -33 + j*(293) -100 + j*(108) -23 + j*(74) -47 + j*(98) -50 + j*(59) -31 + j*(103) -155 + j*(132) -241 + j*(-50) -63 + j*(-202) --117 + j*(-78) --51 + j*(88) -74 + j*(75) -110 + j*(15) -144 + j*(-58) -79 + j*(-200) --139 + j*(-191) --190 + j*(33) --8 + j*(96) -7 + j*(-53) --159 + j*(1) --78 + j*(213) -152 + j*(168) -161 + j*(-13) -86 + j*(-45) -86 + j*(-71) --5 + j*(-117) --72 + j*(0) -64 + j*(57) -101 + j*(-98) --54 + j*(-114) --33 + j*(19) -74 + j*(-61) --57 + j*(-158) --146 + j*(-16) --35 + j*(30) --71 + j*(-45) --130 + j*(91) -86 + j*(144) -123 + j*(-132) --199 + j*(-146) --197 + j*(214) -173 + j*(206) -166 + j*(-143) --147 + j*(-138) --156 + j*(122) -28 + j*(158) -74 + j*(79) -92 + j*(67) -139 + j*(16) -139 + j*(-55) -127 + j*(-139) -9 + j*(-258) --230 + j*(-187) --246 + j*(93) --12 + j*(165) -50 + j*(8) --50 + j*(1) -4 + j*(67) -45 + j*(-31) --97 + j*(-49) --100 + j*(129) -100 + j*(128) -93 + j*(-74) --117 + j*(-50) --92 + j*(185) -175 + j*(204) -278 + j*(-47) -117 + j*(-231) --79 + j*(-203) --175 + j*(-86) --193 + j*(62) --84 + j*(206) -129 + j*(198) -231 + j*(-6) -102 + j*(-179) --88 + j*(-148) --156 + j*(2) --88 + j*(147) -98 + j*(192) -267 + j*(23) -168 + j*(-235) --110 + j*(-236) --180 + j*(1) --2 + j*(80) -46 + j*(-66) --109 + j*(-97) --160 + j*(77) -1 + j*(176) -139 + j*(74) -117 + j*(-64) -33 + j*(-117) --59 + j*(-117) --161 + j*(-37) --133 + j*(150) -104 + j*(219) -291 + j*(-16) -139 + j*(-310) --199 + j*(-314) --378 + j*(-46) --284 + j*(239) --25 + j*(341) -194 + j*(214) -214 + j*(10) -110 + j*(-87) -23 + j*(-93) --47 + j*(-53) --41 + j*(39) -58 + j*(28) -17 + j*(-89) --136 + j*(-11) --37 + j*(188) -182 + j*(91) -91 + j*(-105) --46 + j*(6) -108 + j*(94) -180 + j*(-86) -37 + j*(-130) -85 + j*(-60) -135 + j*(-260) --185 + j*(-387) --421 + j*(-73) --231 + j*(197) --42 + j*(148) --9 + j*(95) -47 + j*(28) --54 + j*(-99) --247 + j*(40) --104 + j*(290) -146 + j*(186) -71 + j*(12) -3 + j*(115) -165 + j*(115) -146 + j*(-84) --47 + j*(-49) -16 + j*(131) -212 + j*(54) -180 + j*(-160) --13 + j*(-214) --140 + j*(-92) --93 + j*(52) -25 + j*(36) --27 + j*(-58) --121 + j*(58) -49 + j*(178) -180 + j*(-21) --45 + j*(-127) --101 + j*(151) -255 + j*(185) -320 + j*(-228) --79 + j*(-355) --247 + j*(-40) --45 + j*(126) -95 + j*(31) -101 + j*(-80) -32 + j*(-185) --139 + j*(-178) --192 + j*(-7) --73 + j*(47) --81 + j*(-33) --180 + j*(51) --69 + j*(201) -110 + j*(124) -83 + j*(-42) --50 + j*(-42) --71 + j*(80) -69 + j*(144) -213 + j*(-8) -88 + j*(-250) --221 + j*(-203) --274 + j*(106) --42 + j*(234) -100 + j*(119) -87 + j*(26) -66 + j*(-14) -21 + j*(-45) --20 + j*(-9) -13 + j*(8) -4 + j*(-40) --59 + j*(-20) --49 + j*(38) --25 + j*(42) --22 + j*(71) -52 + j*(76) -53 + j*(-28) --86 + j*(-1) --26 + j*(194) -226 + j*(132) -187 + j*(-146) --77 + j*(-126) --53 + j*(110) -164 + j*(88) -166 + j*(-105) -30 + j*(-148) --29 + j*(-98) --57 + j*(-61) --66 + j*(14) -28 + j*(76) -149 + j*(-6) -115 + j*(-182) --88 + j*(-221) --185 + j*(-33) --21 + j*(79) -82 + j*(-96) --125 + j*(-214) --287 + j*(-10) --146 + j*(173) --12 + j*(116) --25 + j*(76) -11 + j*(93) -31 + j*(28) --45 + j*(43) -14 + j*(156) -173 + j*(86) -139 + j*(-89) -6 + j*(-100) --23 + j*(-38) --27 + j*(-8) -13 + j*(44) -117 + j*(-16) -51 + j*(-180) --146 + j*(-136) --134 + j*(37) --23 + j*(21) --78 + j*(-34) --112 + j*(47) --48 + j*(56) --108 + j*(28) --144 + j*(182) -54 + j*(279) -195 + j*(128) -129 + j*(27) -136 + j*(62) -218 + j*(-19) -161 + j*(-156) -49 + j*(-178) --12 + j*(-179) --121 + j*(-172) --220 + j*(-45) --171 + j*(123) --26 + j*(193) -110 + j*(132) -129 + j*(3) -39 + j*(-29) -65 + j*(55) -211 + j*(-35) -109 + j*(-274) --185 + j*(-220) --183 + j*(54) -26 + j*(59) --7 + j*(-98) --143 + j*(-27) --61 + j*(94) -26 + j*(10) --83 + j*(-47) --158 + j*(103) --2 + j*(258) -251 + j*(173) -300 + j*(-131) -28 + j*(-305) --199 + j*(-117) --73 + j*(78) -47 + j*(-50) --134 + j*(-120) --199 + j*(110) -38 + j*(192) -126 + j*(-15) --35 + j*(-98) --124 + j*(2) --126 + j*(100) --49 + j*(239) -209 + j*(235) -294 + j*(-68) -13 + j*(-176) --31 + j*(79) -262 + j*(23) -144 + j*(-357) --298 + j*(-252) --250 + j*(172) -72 + j*(168) -68 + j*(1) -73 + j*(57) -232 + j*(-107) --36 + j*(-400) --446 + j*(-110) --196 + j*(342) -204 + j*(129) --45 + j*(-166) --267 + j*(185) -194 + j*(424) -521 + j*(-70) -105 + j*(-478) --304 + j*(-208) --165 + j*(102) -0 + j*(15) --111 + j*(-33) --99 + j*(129) -104 + j*(97) -68 + j*(-135) --190 + j*(-107) --194 + j*(148) -14 + j*(179) -18 + j*(48) --71 + j*(122) -74 + j*(238) -245 + j*(97) -179 + j*(-89) -52 + j*(-107) --18 + j*(-81) --87 + j*(2) --12 + j*(144) -167 + j*(89) -122 + j*(-79) --1 + j*(-8) -138 + j*(82) -232 + j*(-118) -33 + j*(-228) --41 + j*(-73) -85 + j*(-91) --19 + j*(-235) --194 + j*(-97) --62 + j*(70) -66 + j*(-56) --55 + j*(-144) --111 + j*(-49) --57 + j*(-36) --92 + j*(-65) --105 + j*(-19) --88 + j*(-44) --190 + j*(-34) --196 + j*(132) --33 + j*(165) --22 + j*(61) --68 + j*(141) -124 + j*(167) -168 + j*(-108) --149 + j*(-180) --244 + j*(127) --2 + j*(221) -33 + j*(65) --71 + j*(139) -95 + j*(257) -263 + j*(78) -151 + j*(-98) -33 + j*(-74) -5 + j*(-63) --97 + j*(-25) --93 + j*(167) -140 + j*(245) -302 + j*(45) -200 + j*(-151) -46 + j*(-136) -48 + j*(-49) -122 + j*(-85) -79 + j*(-211) --98 + j*(-222) --182 + j*(-57) --70 + j*(57) -24 + j*(-21) --59 + j*(-98) --161 + j*(4) --69 + j*(160) -134 + j*(116) -154 + j*(-108) --57 + j*(-182) --161 + j*(-10) --42 + j*(93) -23 + j*(33) -18 + j*(42) -133 + j*(21) -133 + j*(-211) --172 + j*(-284) --332 + j*(1) --152 + j*(195) --28 + j*(141) --17 + j*(161) -130 + j*(177) -220 + j*(-8) -100 + j*(-139) -10 + j*(-124) --48 + j*(-148) --190 + j*(-85) --171 + j*(121) -27 + j*(141) -56 + j*(-9) --40 + j*(-22) --37 + j*(16) --66 + j*(1) --113 + j*(91) -0 + j*(174) -98 + j*(89) -57 + j*(23) -44 + j*(35) -30 + j*(5) --23 + j*(73) -120 + j*(161) -271 + j*(-38) -64 + j*(-243) --151 + j*(-73) --24 + j*(100) -72 + j*(12) -13 + j*(2) -74 + j*(50) -113 + j*(-50) -20 + j*(-53) -93 + j*(24) -184 + j*(-129) --1 + j*(-242) --82 + j*(-81) -67 + j*(-92) --29 + j*(-284) --260 + j*(-185) --206 + j*(-7) --161 + j*(-64) --305 + j*(-4) --243 + j*(209) --74 + j*(191) --119 + j*(148) --81 + j*(298) -144 + j*(272) -154 + j*(89) -76 + j*(119) -211 + j*(135) -238 + j*(-69) -45 + j*(-116) -28 + j*(28) -146 + j*(1) -110 + j*(-107) -45 + j*(-105) -16 + j*(-117) --69 + j*(-81) --28 + j*(48) -132 + j*(-17) -42 + j*(-207) --167 + j*(-116) --84 + j*(81) -78 + j*(-4) --19 + j*(-136) --136 + j*(-39) --55 + j*(69) -43 + j*(12) -22 + j*(-86) --69 + j*(-117) --155 + j*(-61) --162 + j*(35) --115 + j*(83) --90 + j*(102) --52 + j*(128) --16 + j*(120) --25 + j*(138) -55 + j*(226) -257 + j*(161) -288 + j*(-102) -76 + j*(-227) --66 + j*(-138) --85 + j*(-68) --132 + j*(-14) --106 + j*(112) -21 + j*(136) -40 + j*(70) -32 + j*(154) -274 + j*(192) -470 + j*(-161) -147 + j*(-558) --358 + j*(-407) --404 + j*(30) --165 + j*(161) --110 + j*(119) --52 + j*(228) -209 + j*(174) -204 + j*(-175) --187 + j*(-217) --269 + j*(175) -78 + j*(296) -209 + j*(49) -89 + j*(-22) -134 + j*(-6) -108 + j*(-174) --145 + j*(-147) --117 + j*(135) -160 + j*(94) -94 + j*(-165) --141 + j*(-80) --43 + j*(127) -132 + j*(31) -54 + j*(-102) --30 + j*(-47) -19 + j*(-6) -48 + j*(-57) -17 + j*(-117) --84 + j*(-141) --181 + j*(-30) --98 + j*(112) -36 + j*(63) -11 + j*(-26) --16 + j*(-16) --29 + j*(-71) --196 + j*(-40) --182 + j*(252) -190 + j*(307) -325 + j*(-54) -77 + j*(-206) -13 + j*(-109) -13 + j*(-216) --254 + j*(-208) --281 + j*(120) -9 + j*(128) --92 + j*(-108) --335 + j*(128) --39 + j*(413) -235 + j*(158) -40 + j*(-4) -47 + j*(185) -272 + j*(43) -58 + j*(-199) --151 + j*(68) -185 + j*(223) -320 + j*(-168) --80 + j*(-320) --244 + j*(13) --34 + j*(158) -46 + j*(89) -90 + j*(115) -222 + j*(21) -141 + j*(-165) --11 + j*(-110) -69 + j*(-47) -57 + j*(-207) --177 + j*(-183) --182 + j*(69) -19 + j*(83) -4 + j*(-45) --62 + j*(29) -73 + j*(46) -56 + j*(-146) --194 + j*(-108) --160 + j*(185) -148 + j*(170) -151 + j*(-126) --126 + j*(-132) --126 + j*(131) -123 + j*(138) -142 + j*(-78) --23 + j*(-88) -12 + j*(37) -146 + j*(-54) -37 + j*(-241) --188 + j*(-173) --185 + j*(35) --38 + j*(55) --45 + j*(-38) --124 + j*(16) --33 + j*(112) -83 + j*(-2) --41 + j*(-153) --229 + j*(-45) --171 + j*(152) --30 + j*(144) --42 + j*(91) --32 + j*(158) -83 + j*(134) -56 + j*(16) --47 + j*(80) -69 + j*(199) -236 + j*(71) -161 + j*(-123) --4 + j*(-136) --93 + j*(-64) --148 + j*(62) --47 + j*(245) -218 + j*(224) -298 + j*(-30) -145 + j*(-163) -47 + j*(-138) --21 + j*(-137) --120 + j*(-38) --23 + j*(128) -176 + j*(43) -117 + j*(-156) --56 + j*(-127) --53 + j*(-14) --11 + j*(-1) -14 + j*(35) -124 + j*(-1) -84 + j*(-180) --141 + j*(-144) --107 + j*(107) -157 + j*(79) -155 + j*(-175) --37 + j*(-204) --59 + j*(-121) --61 + j*(-178) --214 + j*(-185) --306 + j*(-16) --241 + j*(144) --115 + j*(222) -52 + j*(216) -165 + j*(67) -101 + j*(-112) --72 + j*(-145) --185 + j*(-23) --122 + j*(134) -55 + j*(108) -33 + j*(-105) --250 + j*(-77) --265 + j*(286) -128 + j*(386) -296 + j*(48) -64 + j*(-122) --53 + j*(13) -15 + j*(66) -23 + j*(66) -108 + j*(94) -180 + j*(-81) --65 + j*(-205) --232 + j*(86) -78 + j*(267) -239 + j*(-42) --71 + j*(-153) --117 + j*(177) -238 + j*(168) -198 + j*(-204) --176 + j*(-141) --97 + j*(228) -262 + j*(150) -208 + j*(-185) --86 + j*(-157) --82 + j*(98) -142 + j*(136) -242 + j*(-37) -164 + j*(-181) -35 + j*(-193) -2 + j*(-112) -82 + j*(-119) -57 + j*(-270) --162 + j*(-302) --274 + j*(-95) --132 + j*(29) --64 + j*(-79) --197 + j*(-99) --213 + j*(50) --98 + j*(53) --172 + j*(-28) --287 + j*(146) --75 + j*(344) -168 + j*(168) -29 + j*(-42) --130 + j*(121) -88 + j*(276) -290 + j*(46) -116 + j*(-192) --108 + j*(-100) --81 + j*(66) -20 + j*(63) -8 + j*(11) --29 + j*(52) -40 + j*(115) -158 + j*(41) -110 + j*(-136) --104 + j*(-132) --139 + j*(93) -78 + j*(148) -141 + j*(-59) --54 + j*(-121) --123 + j*(51) -1 + j*(128) -66 + j*(78) -93 + j*(68) -163 + j*(-1) -104 + j*(-146) --76 + j*(-124) --93 + j*(61) -79 + j*(119) -188 + j*(-23) -113 + j*(-179) --43 + j*(-187) --100 + j*(-78) --45 + j*(-51) --98 + j*(-113) --233 + j*(1) --123 + j*(232) -156 + j*(174) -148 + j*(-90) --66 + j*(-91) --35 + j*(91) -155 + j*(33) -121 + j*(-197) --119 + j*(-256) --310 + j*(-78) --269 + j*(197) -3 + j*(300) -182 + j*(91) -19 + j*(-75) --105 + j*(106) -130 + j*(225) -284 + j*(-35) -54 + j*(-224) --133 + j*(-47) --6 + j*(124) -160 + j*(51) -171 + j*(-109) -57 + j*(-223) --130 + j*(-194) --180 + j*(4) --11 + j*(92) -74 + j*(-50) --52 + j*(-118) --97 + j*(-11) --3 + j*(7) -8 + j*(-91) --86 + j*(-139) --194 + j*(-109) --279 + j*(10) --231 + j*(179) --83 + j*(216) --47 + j*(160) --45 + j*(217) -106 + j*(235) -167 + j*(57) --2 + j*(1) --26 + j*(185) -186 + j*(215) -257 + j*(21) -141 + j*(-59) -119 + j*(-13) -165 + j*(-59) -110 + j*(-144) -8 + j*(-139) --33 + j*(-65) -11 + j*(-12) -63 + j*(-57) --11 + j*(-122) --100 + j*(-14) -40 + j*(100) -182 + j*(-69) --8 + j*(-233) --179 + j*(-41) -19 + j*(117) -161 + j*(-88) --35 + j*(-218) --136 + j*(-60) --17 + j*(-28) --75 + j*(-149) --241 + j*(-43) --153 + j*(168) -45 + j*(142) -80 + j*(20) -69 + j*(-28) -76 + j*(-134) --96 + j*(-247) --325 + j*(-105) --283 + j*(164) --85 + j*(204) --66 + j*(121) --98 + j*(215) -92 + j*(301) -265 + j*(112) -143 + j*(-83) -3 + j*(-4) -103 + j*(76) -180 + j*(-63) -59 + j*(-177) --62 + j*(-136) --111 + j*(-74) --144 + j*(11) --81 + j*(103) -1 + j*(78) --28 + j*(57) -13 + j*(127) -128 + j*(42) --3 + j*(-99) --172 + j*(89) -55 + j*(308) -307 + j*(102) -168 + j*(-109) -77 + j*(-8) -207 + j*(-42) -105 + j*(-216) --57 + j*(-90) -122 + j*(7) -168 + j*(-257) --159 + j*(-298) --193 + j*(23) -97 + j*(0) -6 + j*(-298) --320 + j*(-202) --291 + j*(93) --113 + j*(110) --132 + j*(59) --149 + j*(163) --18 + j*(245) -150 + j*(180) -192 + j*(-21) --12 + j*(-139) --167 + j*(93) -133 + j*(296) -422 + j*(-64) -78 + j*(-441) --328 + j*(-182) --164 + j*(155) -32 + j*(40) --94 + j*(-28) --88 + j*(132) -64 + j*(98) -8 + j*(21) -30 + j*(139) -245 + j*(49) -146 + j*(-260) --206 + j*(-195) --180 + j*(150) -134 + j*(155) -177 + j*(-130) --66 + j*(-232) --235 + j*(-58) --152 + j*(147) -47 + j*(132) -57 + j*(-49) --119 + j*(-60) --140 + j*(104) --33 + j*(127) --69 + j*(110) --46 + j*(278) -240 + j*(312) -383 + j*(20) -192 + j*(-167) -70 + j*(-82) -132 + j*(-64) -102 + j*(-156) -2 + j*(-146) --12 + j*(-86) -6 + j*(-78) -10 + j*(-89) -1 + j*(-121) --66 + j*(-136) --112 + j*(-70) --74 + j*(-28) --65 + j*(-53) --93 + j*(-38) --75 + j*(-33) --134 + j*(-76) --257 + j*(40) --152 + j*(264) -122 + j*(228) -159 + j*(-25) --31 + j*(-98) --112 + j*(28) --53 + j*(109) -6 + j*(115) -55 + j*(113) -119 + j*(81) -160 + j*(-12) -98 + j*(-134) --69 + j*(-132) --108 + j*(42) -71 + j*(84) -102 + j*(-123) --149 + j*(-164) --233 + j*(99) --30 + j*(226) -82 + j*(144) -124 + j*(140) -285 + j*(53) -253 + j*(-241) --65 + j*(-312) --187 + j*(-81) --78 + j*(-13) --146 + j*(-58) --225 + j*(144) -30 + j*(315) -274 + j*(113) -185 + j*(-124) -39 + j*(-122) -31 + j*(-100) --21 + j*(-143) --119 + j*(-92) --108 + j*(5) --59 + j*(8) --90 + j*(-4) --119 + j*(73) --38 + j*(153) -69 + j*(119) -79 + j*(35) -44 + j*(34) -98 + j*(56) -162 + j*(-49) -58 + j*(-182) --121 + j*(-129) --134 + j*(50) -6 + j*(117) -101 + j*(33) -76 + j*(-61) -10 + j*(-74) --4 + j*(-46) -1 + j*(-69) --63 + j*(-79) --99 + j*(14) -19 + j*(67) -86 + j*(-82) --101 + j*(-184) --262 + j*(23) --74 + j*(246) -199 + j*(108) -130 + j*(-200) --197 + j*(-220) --322 + j*(87) --86 + j*(292) -134 + j*(148) -47 + j*(-25) --66 + j*(71) -64 + j*(151) -130 + j*(-6) --42 + j*(-47) --55 + j*(150) -165 + j*(156) -183 + j*(-57) -16 + j*(-71) -38 + j*(48) -134 + j*(-11) -57 + j*(-99) --16 + j*(-20) -64 + j*(59) -183 + j*(12) -243 + j*(-139) -146 + j*(-344) --136 + j*(-390) --310 + j*(-160) --190 + j*(20) --101 + j*(-61) --244 + j*(-89) --314 + j*(119) --135 + j*(274) -37 + j*(193) -9 + j*(93) --30 + j*(167) -136 + j*(244) -330 + j*(52) -206 + j*(-245) --100 + j*(-232) --156 + j*(-1) --20 + j*(57) --2 + j*(-8) --21 + j*(8) -9 + j*(-23) --84 + j*(-71) --172 + j*(70) --40 + j*(197) -71 + j*(134) -69 + j*(122) -204 + j*(131) -289 + j*(-105) -48 + j*(-267) --117 + j*(-80) -29 + j*(9) -35 + j*(-146) --147 + j*(-115) --127 + j*(57) --21 + j*(53) --33 + j*(38) -35 + j*(74) -91 + j*(-54) --83 + j*(-115) --143 + j*(86) -59 + j*(139) -90 + j*(-30) --27 + j*(-8) -72 + j*(67) -134 + j*(-110) --86 + j*(-178) --147 + j*(43) -63 + j*(65) -36 + j*(-163) --241 + j*(-127) --261 + j*(175) --10 + j*(271) -105 + j*(127) -33 + j*(82) -76 + j*(185) -282 + j*(139) -342 + j*(-134) -117 + j*(-313) --91 + j*(-217) --93 + j*(-85) --62 + j*(-66) --66 + j*(-48) --45 + j*(-54) --103 + j*(-93) --198 + j*(10) --96 + j*(158) -62 + j*(83) --5 + j*(-36) --83 + j*(56) -40 + j*(118) -115 + j*(-21) --5 + j*(-117) --124 + j*(-46) --124 + j*(76) --24 + j*(152) -101 + j*(85) -59 + j*(-54) --82 + j*(-16) --40 + j*(128) -96 + j*(98) -89 + j*(8) -78 + j*(14) -117 + j*(-49) -11 + j*(-134) --95 + j*(-16) -24 + j*(91) -124 + j*(-26) -34 + j*(-121) --38 + j*(-86) --65 + j*(-70) --132 + j*(-6) --73 + j*(136) -105 + j*(129) -165 + j*(-20) -114 + j*(-127) -27 + j*(-206) --149 + j*(-214) --279 + j*(-35) --199 + j*(165) --30 + j*(222) -127 + j*(180) -237 + j*(3) -117 + j*(-216) --130 + j*(-172) --134 + j*(24) --23 + j*(24) --66 + j*(-16) --55 + j*(66) -30 + j*(5) --110 + j*(-68) --191 + j*(171) -123 + j*(295) -298 + j*(-30) -11 + j*(-223) --153 + j*(-2) -4 + j*(105) -43 + j*(1) --23 + j*(31) -62 + j*(81) -114 + j*(-18) -42 + j*(-70) -21 + j*(-55) --17 + j*(-88) --118 + j*(-25) --51 + j*(135) -152 + j*(98) -173 + j*(-116) --1 + j*(-206) --134 + j*(-121) --135 + j*(-4) --72 + j*(30) --74 + j*(0) --143 + j*(57) --77 + j*(211) -144 + j*(200) -202 + j*(-10) -59 + j*(-81) -58 + j*(10) -178 + j*(-93) -22 + j*(-322) --337 + j*(-206) --330 + j*(221) -78 + j*(327) -239 + j*(-14) --35 + j*(-155) --123 + j*(98) -151 + j*(136) -168 + j*(-165) --141 + j*(-185) --166 + j*(93) -47 + j*(113) -43 + j*(-6) -30 + j*(49) -165 + j*(-33) -17 + j*(-255) --269 + j*(-81) --86 + j*(231) -225 + j*(40) -30 + j*(-259) --252 + j*(-91) --139 + j*(146) -13 + j*(98) -14 + j*(58) -77 + j*(35) -42 + j*(-102) --147 + j*(-42) --55 + j*(191) -230 + j*(76) -115 + j*(-262) --256 + j*(-185) --249 + j*(168) --23 + j*(28) -142 + j*(89) -243 + j*(-152) --11 + j*(-301) --160 + j*(-95) --9 + j*(-13) --18 + j*(-156) --180 + j*(-100) --137 + j*(49) --59 + j*(32) --93 + j*(57) -9 + j*(139) -139 + j*(30) -85 + j*(-95) -49 + j*(-113) --1 + j*(-236) --292 + j*(-232) --390 + j*(163) -18 + j*(347) -232 + j*(-16) --69 + j*(-199) --178 + j*(31) --9 + j*(29) --153 + j*(-123) --350 + j*(132) --78 + j*(395) -177 + j*(175) --3 + j*(17) --54 + j*(233) -233 + j*(250) -274 + j*(-47) -47 + j*(-99) -62 + j*(39) -161 + j*(-92) --80 + j*(-226) --301 + j*(77) --18 + j*(404) -385 + j*(230) -369 + j*(-156) -106 + j*(-264) --22 + j*(-159) --18 + j*(-98) --25 + j*(-91) --62 + j*(-67) --71 + j*(3) -14 + j*(64) -128 + j*(-19) -71 + j*(-185) --119 + j*(-175) --159 + j*(-13) --60 + j*(39) --55 + j*(-1) --75 + j*(60) -33 + j*(105) -115 + j*(1) -66 + j*(-100) -3 + j*(-122) --59 + j*(-150) --186 + j*(-126) --264 + j*(36) --168 + j*(209) -22 + j*(231) -126 + j*(107) -83 + j*(4) -36 + j*(27) -107 + j*(28) -112 + j*(-110) --60 + j*(-147) --120 + j*(21) -26 + j*(76) -58 + j*(-45) --23 + j*(-40) -44 + j*(-8) -48 + j*(-170) --195 + j*(-199) --287 + j*(54) --105 + j*(174) --40 + j*(91) --74 + j*(122) -21 + j*(158) -40 + j*(59) --60 + j*(115) -76 + j*(275) -334 + j*(137) -289 + j*(-160) -68 + j*(-228) --31 + j*(-156) --88 + j*(-124) --161 + j*(-33) --124 + j*(107) -8 + j*(153) -107 + j*(76) -85 + j*(-28) --11 + j*(-13) -36 + j*(100) -209 + j*(28) -150 + j*(-202) --91 + j*(-184) --93 + j*(16) -47 + j*(-1) --6 + j*(-98) --74 + j*(-21) -4 + j*(15) -9 + j*(-45) --18 + j*(-18) -45 + j*(-42) --28 + j*(-154) --188 + j*(-57) --95 + j*(119) -54 + j*(37) --26 + j*(-59) --64 + j*(36) -48 + j*(21) -4 + j*(-108) --123 + j*(-68) --115 + j*(13) --122 + j*(18) --150 + j*(101) --64 + j*(182) -11 + j*(168) -74 + j*(197) -255 + j*(128) -258 + j*(-156) --20 + j*(-245) --132 + j*(-64) --83 + j*(-25) --188 + j*(30) --97 + j*(302) -292 + j*(246) -298 + j*(-159) --21 + j*(-179) -32 + j*(19) -153 + j*(-161) --119 + j*(-269) --227 + j*(11) -1 + j*(71) --40 + j*(-97) --175 + j*(52) -53 + j*(170) -153 + j*(-105) --145 + j*(-195) --250 + j*(85) --49 + j*(207) -48 + j*(129) -69 + j*(92) -109 + j*(19) -41 + j*(-40) -16 + j*(28) -91 + j*(10) -21 + j*(-59) --27 + j*(63) -158 + j*(100) -209 + j*(-114) -35 + j*(-167) -47 + j*(-66) -111 + j*(-199) --112 + j*(-295) --257 + j*(-64) --81 + j*(86) -22 + j*(-27) --33 + j*(-78) --40 + j*(-95) --135 + j*(-163) --308 + j*(-43) --243 + j*(182) --76 + j*(193) --74 + j*(161) --16 + j*(262) -194 + j*(226) -250 + j*(6) -122 + j*(-113) -16 + j*(-117) --87 + j*(-83) --140 + j*(62) --11 + j*(180) -116 + j*(110) -89 + j*(40) -112 + j*(82) -233 + j*(13) -198 + j*(-182) --1 + j*(-221) --87 + j*(-75) -7 + j*(4) -69 + j*(-75) --1 + j*(-138) --55 + j*(-95) --35 + j*(-101) --127 + j*(-163) --291 + j*(-27) --199 + j*(238) -83 + j*(233) -132 + j*(16) --4 + j*(-6) -42 + j*(98) -173 + j*(21) -136 + j*(-142) -4 + j*(-189) --103 + j*(-150) --156 + j*(-56) --114 + j*(25) --72 + j*(-2) --146 + j*(-1) --158 + j*(125) --50 + j*(185) -4 + j*(173) -88 + j*(221) -277 + j*(117) -223 + j*(-158) --43 + j*(-142) -3 + j*(74) -201 + j*(-54) -4 + j*(-277) --254 + j*(-63) --64 + j*(196) -165 + j*(43) -50 + j*(-132) --64 + j*(-62) --34 + j*(-21) --73 + j*(-23) --63 + j*(88) -105 + j*(88) -138 + j*(-120) --75 + j*(-207) --221 + j*(-44) --150 + j*(121) --31 + j*(136) -4 + j*(95) --1 + j*(103) -50 + j*(145) -151 + j*(125) -222 + j*(25) -218 + j*(-111) -110 + j*(-235) --87 + j*(-225) --169 + j*(-39) --33 + j*(73) -58 + j*(-28) --32 + j*(-81) --56 + j*(-4) -0 + j*(-13) --52 + j*(-40) --47 + j*(54) -88 + j*(6) --13 + j*(-171) --248 + j*(-30) --103 + j*(257) -195 + j*(141) -110 + j*(-98) --19 + j*(-1) -159 + j*(16) -120 + j*(-291) --305 + j*(-276) --378 + j*(201) -63 + j*(371) -286 + j*(28) -67 + j*(-182) --76 + j*(-67) --17 + j*(-21) --61 + j*(-85) --170 + j*(4) --101 + j*(160) -56 + j*(147) -92 + j*(47) -78 + j*(16) -103 + j*(-33) -47 + j*(-131) --84 + j*(-116) --113 + j*(-16) --83 + j*(1) --139 + j*(10) --166 + j*(136) --43 + j*(240) -93 + j*(202) -138 + j*(125) -150 + j*(73) -153 + j*(25) -153 + j*(-23) -118 + j*(-97) --18 + j*(-105) --68 + j*(83) -180 + j*(184) -353 + j*(-104) -77 + j*(-334) --151 + j*(-103) -63 + j*(66) -168 + j*(-168) --89 + j*(-233) --119 + j*(25) -132 + j*(16) -107 + j*(-228) --86 + j*(-214) --54 + j*(-138) --92 + j*(-265) --349 + j*(-207) --356 + j*(107) --93 + j*(160) --73 + j*(-28) --248 + j*(10) --212 + j*(209) --37 + j*(228) -18 + j*(128) --33 + j*(85) --90 + j*(137) --46 + j*(281) -199 + j*(336) -417 + j*(77) -261 + j*(-259) --77 + j*(-247) --156 + j*(1) --24 + j*(88) -17 + j*(42) -16 + j*(64) -92 + j*(48) -74 + j*(-57) --51 + j*(-31) --7 + j*(107) -146 + j*(42) -68 + j*(-126) --114 + j*(-33) --16 + j*(158) -170 + j*(69) -87 + j*(-78) --1 + j*(31) -176 + j*(82) -247 + j*(-149) -19 + j*(-266) --98 + j*(-95) -27 + j*(-35) -33 + j*(-168) --127 + j*(-173) --180 + j*(-40) --136 + j*(45) --74 + j*(109) -67 + j*(114) -138 + j*(-57) --23 + j*(-173) --140 + j*(-45) --43 + j*(23) --66 + j*(-90) --259 + j*(13) --144 + j*(330) -278 + j*(287) -363 + j*(-161) --17 + j*(-372) --299 + j*(-127) --216 + j*(142) --33 + j*(185) -62 + j*(124) -99 + j*(53) -91 + j*(-22) -33 + j*(-68) --33 + j*(-50) --51 + j*(11) -7 + j*(47) -59 + j*(-15) --10 + j*(-90) --110 + j*(-23) --59 + j*(87) -34 + j*(46) --17 + j*(-21) --74 + j*(53) -9 + j*(121) -81 + j*(61) -57 + j*(22) -82 + j*(31) -119 + j*(-49) -18 + j*(-129) --86 + j*(-42) --18 + j*(55) -60 + j*(-11) --16 + j*(-70) --66 + j*(14) -22 + j*(47) -23 + j*(-51) --113 + j*(-11) --48 + j*(196) -238 + j*(147) -247 + j*(-192) --85 + j*(-257) --155 + j*(30) -103 + j*(41) -40 + j*(-253) --333 + j*(-172) --313 + j*(243) -45 + j*(299) -109 + j*(74) --7 + j*(95) -122 + j*(183) -224 + j*(11) -69 + j*(-73) -57 + j*(95) -303 + j*(52) -310 + j*(-268) -7 + j*(-387) --173 + j*(-211) --130 + j*(-76) --92 + j*(-74) --115 + j*(-60) --124 + j*(-13) --91 + j*(41) --10 + j*(51) -42 + j*(-41) --47 + j*(-139) --182 + j*(-78) --173 + j*(54) --92 + j*(66) --122 + j*(40) --153 + j*(150) --4 + j*(240) -147 + j*(111) -57 + j*(-50) --78 + j*(25) -3 + j*(144) -118 + j*(59) -32 + j*(-44) --53 + j*(49) -57 + j*(134) -166 + j*(28) -100 + j*(-100) --23 + j*(-94) --69 + j*(-5) --24 + j*(75) -73 + j*(71) -105 + j*(-28) -19 + j*(-87) --48 + j*(-28) --14 + j*(33) -34 + j*(14) -28 + j*(-35) --40 + j*(-55) --118 + j*(28) --57 + j*(181) -138 + j*(190) -226 + j*(35) -182 + j*(-69) -153 + j*(-136) -42 + j*(-231) --151 + j*(-138) --90 + j*(93) -134 + j*(37) -58 + j*(-165) --120 + j*(-41) -66 + j*(122) -249 + j*(-115) -25 + j*(-331) --183 + j*(-188) --133 + j*(-76) --165 + j*(-93) --202 + j*(42) --27 + j*(93) --12 + j*(-100) --242 + j*(-66) --185 + j*(194) -54 + j*(130) --50 + j*(-53) --193 + j*(125) -37 + j*(274) -191 + j*(54) -31 + j*(-66) --7 + j*(38) -71 + j*(-16) --44 + j*(-88) --101 + j*(44) -20 + j*(53) --57 + j*(-65) --210 + j*(97) --16 + j*(304) -215 + j*(141) -97 + j*(-46) --6 + j*(60) -120 + j*(99) -136 + j*(-38) -18 + j*(-38) -42 + j*(48) -107 + j*(1) -57 + j*(-47) -26 + j*(5) -81 + j*(33) -141 + j*(0) -173 + j*(-95) -95 + j*(-210) --70 + j*(-194) --105 + j*(-44) -3 + j*(1) -30 + j*(-78) --32 + j*(-98) --53 + j*(-66) --62 + j*(-49) --61 + j*(-18) --31 + j*(-13) --39 + j*(-23) --13 + j*(19) -91 + j*(-51) --1 + j*(-260) --320 + j*(-216) --397 + j*(143) --115 + j*(337) -115 + j*(214) -139 + j*(40) -49 + j*(-75) --118 + j*(-44) --129 + j*(173) -124 + j*(238) -250 + j*(3) -105 + j*(-143) -11 + j*(-124) --68 + j*(-156) --247 + j*(-36) --146 + j*(260) -207 + j*(206) -195 + j*(-151) --132 + j*(-167) --176 + j*(112) -36 + j*(192) -151 + j*(66) -110 + j*(-78) --63 + j*(-106) --148 + j*(112) -112 + j*(264) -325 + j*(5) -118 + j*(-218) --31 + j*(-66) -116 + j*(-28) -83 + j*(-211) --91 + j*(-182) --86 + j*(-112) --183 + j*(-161) --344 + j*(81) --52 + j*(357) -272 + j*(78) -11 + j*(-212) --203 + j*(57) -82 + j*(208) -194 + j*(-78) --54 + j*(-166) --121 + j*(7) --37 + j*(44) --34 + j*(38) -3 + j*(48) --25 + j*(-1) --94 + j*(120) -136 + j*(245) -339 + j*(-54) -30 + j*(-305) --209 + j*(-25) -49 + j*(156) -170 + j*(-87) --35 + j*(-169) --88 + j*(-43) --66 + j*(-39) --115 + j*(36) -23 + j*(114) -80 + j*(-83) --192 + j*(-81) --143 + j*(287) -305 + j*(229) -269 + j*(-241) --158 + j*(-226) --134 + j*(123) -133 + j*(91) -112 + j*(-100) -21 + j*(-112) --12 + j*(-141) --151 + j*(-126) --176 + j*(70) -25 + j*(135) -128 + j*(-49) --12 + j*(-217) --269 + j*(-181) --410 + j*(129) --139 + j*(447) -255 + j*(280) -152 + j*(-53) --63 + j*(101) -237 + j*(246) -395 + j*(-192) --105 + j*(-402) --348 + j*(83) -75 + j*(325) -288 + j*(1) -97 + j*(-154) -42 + j*(-95) -8 + j*(-169) --168 + j*(-93) --78 + j*(130) -153 + j*(20) -26 + j*(-214) --209 + j*(-102) --149 + j*(105) --20 + j*(105) -6 + j*(71) -43 + j*(59) -47 + j*(8) -25 + j*(18) -91 + j*(8) -78 + j*(-132) --117 + j*(-150) --182 + j*(47) --35 + j*(133) -28 + j*(59) -6 + j*(62) -74 + j*(63) -69 + j*(-37) --41 + j*(-14) -18 + j*(109) -173 + j*(21) -81 + j*(-160) --103 + j*(-80) --34 + j*(78) -88 + j*(11) -18 + j*(-66) --6 + j*(19) -110 + j*(-4) -63 + j*(-157) --106 + j*(-113) --64 + j*(42) -68 + j*(-10) -10 + j*(-130) --93 + j*(-92) --92 + j*(-38) --109 + j*(-23) --107 + j*(44) --27 + j*(44) --62 + j*(-31) --153 + j*(49) --58 + j*(158) -23 + j*(69) --84 + j*(64) --25 + j*(244) -223 + j*(180) -191 + j*(-71) -10 + j*(-33) -115 + j*(78) -214 + j*(-107) -6 + j*(-233) --123 + j*(-74) --34 + j*(-1) --45 + j*(-49) --81 + j*(33) -39 + j*(55) -24 + j*(-92) --163 + j*(-40) --100 + j*(196) -172 + j*(156) -171 + j*(-119) --78 + j*(-161) --156 + j*(51) -6 + j*(148) -101 + j*(45) -38 + j*(-13) -35 + j*(58) -165 + j*(34) -175 + j*(-161) --36 + j*(-250) --189 + j*(-88) --101 + j*(69) -21 + j*(22) --23 + j*(-78) --138 + j*(-33) --126 + j*(103) --8 + j*(134) -12 + j*(66) --43 + j*(127) -112 + j*(260) -383 + j*(100) -330 + j*(-258) -23 + j*(-337) --91 + j*(-199) --110 + j*(-185) --264 + j*(-117) --245 + j*(149) -30 + j*(205) -112 + j*(-11) --33 + j*(-68) --39 + j*(21) -15 + j*(-33) --98 + j*(-83) --180 + j*(64) --58 + j*(203) -113 + j*(162) -166 + j*(11) -74 + j*(-98) --35 + j*(-45) -30 + j*(42) -125 + j*(-70) --13 + j*(-211) --194 + j*(-110) --166 + j*(54) --81 + j*(71) --74 + j*(62) --68 + j*(71) --101 + j*(92) --91 + j*(233) -141 + j*(305) -310 + j*(66) -131 + j*(-126) -1 + j*(6) -140 + j*(49) -129 + j*(-116) --45 + j*(-67) -49 + j*(110) -257 + j*(-18) -165 + j*(-269) --75 + j*(-278) --187 + j*(-138) --194 + j*(9) --90 + j*(130) -77 + j*(91) -92 + j*(-62) --18 + j*(-95) --43 + j*(-37) --19 + j*(-49) --71 + j*(-74) --126 + j*(-21) --115 + j*(54) --66 + j*(91) --29 + j*(91) --13 + j*(107) -62 + j*(142) -178 + j*(54) -115 + j*(-120) --73 + j*(-76) --18 + j*(118) -209 + j*(47) -165 + j*(-208) --64 + j*(-236) --146 + j*(-114) --171 + j*(-52) --197 + j*(86) --19 + j*(215) -181 + j*(56) -65 + j*(-170) --143 + j*(-106) --127 + j*(49) --51 + j*(53) --61 + j*(43) --43 + j*(68) --45 + j*(40) --124 + j*(97) --59 + j*(291) -234 + j*(317) -419 + j*(34) -269 + j*(-258) -0 + j*(-274) --101 + j*(-117) --46 + j*(-37) --21 + j*(-72) --90 + j*(-83) --137 + j*(1) --93 + j*(83) --21 + j*(95) -9 + j*(76) -27 + j*(77) -75 + j*(76) -117 + j*(24) -112 + j*(-40) -88 + j*(-76) -69 + j*(-136) --57 + j*(-201) --231 + j*(-71) --143 + j*(190) -165 + j*(153) -162 + j*(-180) --190 + j*(-209) --260 + j*(144) -57 + j*(249) -159 + j*(-2) --35 + j*(-54) --25 + j*(131) -188 + j*(100) -193 + j*(-130) -9 + j*(-199) --107 + j*(-110) --122 + j*(3) --39 + j*(104) -126 + j*(49) -95 + j*(-164) --158 + j*(-164) --190 + j*(103) -61 + j*(153) -91 + j*(-58) --81 + j*(-35) -20 + j*(119) -177 + j*(-62) --69 + j*(-240) --276 + j*(49) -34 + j*(281) -285 + j*(-22) -19 + j*(-272) --194 + j*(-66) --27 + j*(69) -28 + j*(-104) --188 + j*(-129) --248 + j*(105) --57 + j*(221) -81 + j*(108) -33 + j*(-18) --84 + j*(-7) --110 + j*(110) --21 + j*(176) -41 + j*(153) -64 + j*(177) -202 + j*(193) -331 + j*(9) -216 + j*(-207) -10 + j*(-214) --82 + j*(-117) --124 + j*(-12) --60 + j*(143) -165 + j*(153) -257 + j*(-86) -69 + j*(-237) --88 + j*(-146) --94 + j*(-47) --86 + j*(23) -16 + j*(106) -173 + j*(-12) -57 + j*(-231) --211 + j*(-134) --149 + j*(158) -141 + j*(144) -181 + j*(-113) --13 + j*(-198) --105 + j*(-86) --56 + j*(-25) --36 + j*(-57) --80 + j*(-63) --96 + j*(-18) --71 + j*(-6) --88 + j*(-24) --124 + j*(11) --108 + j*(51) --127 + j*(59) --153 + j*(185) -56 + j*(325) -334 + j*(108) -181 + j*(-267) --224 + j*(-204) --241 + j*(168) -48 + j*(234) -113 + j*(47) -2 + j*(36) -62 + j*(136) -213 + j*(46) -154 + j*(-175) --127 + j*(-190) --233 + j*(129) -107 + j*(342) -432 + j*(21) -193 + j*(-389) --214 + j*(-258) --167 + j*(44) --10 + j*(-9) --145 + j*(-54) --161 + j*(165) -77 + j*(206) -124 + j*(30) -33 + j*(39) -134 + j*(86) -187 + j*(-78) -29 + j*(-138) -6 + j*(-11) -123 + j*(-55) -44 + j*(-189) --88 + j*(-116) --22 + j*(-35) -0 + j*(-133) --151 + j*(-132) --167 + j*(40) --13 + j*(62) --16 + j*(-68) --141 + j*(-30) --83 + j*(93) -20 + j*(7) --124 + j*(-78) --226 + j*(129) -3 + j*(272) -150 + j*(62) --44 + j*(-34) --73 + j*(190) -191 + j*(197) -207 + j*(-57) -29 + j*(-50) -119 + j*(46) -187 + j*(-148) --65 + j*(-232) --148 + j*(8) -50 + j*(37) --4 + j*(-137) --182 + j*(-20) --45 + j*(158) -105 + j*(30) --4 + j*(-66) --45 + j*(23) -9 + j*(13) --52 + j*(4) --19 + j*(126) -153 + j*(77) -108 + j*(-109) --53 + j*(-69) -4 + j*(52) -96 + j*(-33) -2 + j*(-112) --69 + j*(-32) --9 + j*(22) -33 + j*(-21) -0 + j*(-68) --62 + j*(-46) --46 + j*(37) -66 + j*(11) -30 + j*(-150) --177 + j*(-118) --157 + j*(100) -45 + j*(60) --61 + j*(-139) --303 + j*(23) --157 + j*(322) -144 + j*(255) -147 + j*(33) -25 + j*(8) -7 + j*(61) -13 + j*(86) -44 + j*(142) -145 + j*(150) -210 + j*(77) -241 + j*(18) -287 + j*(-81) -238 + j*(-244) -66 + j*(-323) --96 + j*(-256) --141 + j*(-104) --23 + j*(-13) -90 + j*(-146) --77 + j*(-325) --341 + j*(-188) --293 + j*(81) --135 + j*(83) --202 + j*(64) --162 + j*(275) -168 + j*(275) -245 + j*(-84) --76 + j*(-218) --229 + j*(35) --60 + j*(180) -47 + j*(89) -11 + j*(42) -16 + j*(64) -44 + j*(25) --13 + j*(-21) --99 + j*(47) --55 + j*(198) -146 + j*(237) -291 + j*(61) -218 + j*(-129) -86 + j*(-161) -35 + j*(-143) --24 + j*(-154) --101 + j*(-112) --124 + j*(-42) --135 + j*(21) --102 + j*(127) -57 + j*(161) -150 + j*(1) -18 + j*(-112) --95 + j*(-10) --21 + j*(100) -87 + j*(67) -116 + j*(-28) -54 + j*(-124) --98 + j*(-109) --133 + j*(77) -69 + j*(161) -203 + j*(-35) -54 + j*(-216) --146 + j*(-167) --224 + j*(-10) --188 + j*(171) -14 + j*(291) -250 + j*(158) -218 + j*(-100) -19 + j*(-132) --16 + j*(-2) -76 + j*(18) -112 + j*(-52) -95 + j*(-116) -40 + j*(-169) --35 + j*(-170) --69 + j*(-151) --129 + j*(-165) --239 + j*(-93) --221 + j*(59) --125 + j*(80) --156 + j*(69) --143 + j*(208) -67 + j*(241) -147 + j*(46) -19 + j*(-22) -22 + j*(44) -44 + j*(-50) --145 + j*(-43) --127 + j*(237) -229 + j*(223) -235 + j*(-165) --151 + j*(-180) --155 + j*(177) -153 + j*(168) -124 + j*(-74) --42 + j*(-8) -70 + j*(91) -132 + j*(-57) --16 + j*(-89) --14 + j*(28) -62 + j*(-24) --44 + j*(-62) --59 + j*(84) -106 + j*(90) -103 + j*(-62) --1 + j*(-36) -63 + j*(8) -52 + j*(-102) --98 + j*(-39) -11 + j*(155) -250 + j*(24) -140 + j*(-243) --105 + j*(-181) --74 + j*(-2) -33 + j*(-24) -21 + j*(-81) -16 + j*(-94) --13 + j*(-163) --137 + j*(-158) --172 + j*(-35) --105 + j*(8) --95 + j*(-8) --82 + j*(9) --61 + j*(-47) --184 + j*(-91) --302 + j*(69) --197 + j*(250) --46 + j*(255) -18 + j*(230) -116 + j*(202) -153 + j*(69) -47 + j*(14) -29 + j*(103) -125 + j*(91) -109 + j*(3) -63 + j*(23) -106 + j*(21) -71 + j*(-32) -40 + j*(49) -194 + j*(54) -204 + j*(-183) --79 + j*(-221) --124 + j*(70) -163 + j*(100) -186 + j*(-181) --60 + j*(-213) --83 + j*(-37) -16 + j*(-55) --47 + j*(-115) --82 + j*(-51) --53 + j*(-66) --161 + j*(-73) --185 + j*(126) -58 + j*(189) -151 + j*(-55) --72 + j*(-164) --196 + j*(13) --115 + j*(155) -0 + j*(219) -228 + j*(195) -358 + j*(-156) --49 + j*(-463) --512 + j*(-72) --199 + j*(486) -371 + j*(288) -278 + j*(-197) --54 + j*(-151) -15 + j*(26) -78 + j*(-95) --64 + j*(-87) -24 + j*(35) -124 + j*(-163) --172 + j*(-277) --321 + j*(49) --28 + j*(185) -27 + j*(-65) --226 + j*(-18) --119 + j*(266) -170 + j*(151) -62 + j*(-108) --163 + j*(-12) --113 + j*(191) -39 + j*(240) -192 + j*(206) -313 + j*(23) -193 + j*(-197) --11 + j*(-159) -4 + j*(-62) --11 + j*(-136) --180 + j*(-67) --119 + j*(165) -107 + j*(136) -76 + j*(-18) -13 + j*(76) -216 + j*(109) -313 + j*(-185) -30 + j*(-404) --285 + j*(-245) --296 + j*(75) --49 + j*(220) -146 + j*(54) -26 + j*(-124) --112 + j*(8) -83 + j*(111) -186 + j*(-162) --133 + j*(-306) --315 + j*(-18) --127 + j*(135) --94 + j*(33) --190 + j*(153) -16 + j*(314) -231 + j*(128) -124 + j*(-67) -6 + j*(-33) --10 + j*(6) --33 + j*(81) -122 + j*(173) -308 + j*(-51) -71 + j*(-327) --252 + j*(-132) --125 + j*(173) -107 + j*(110) -95 + j*(-14) -96 + j*(-24) -103 + j*(-139) --78 + j*(-181) --139 + j*(-2) -4 + j*(33) --23 + j*(-80) --119 + j*(13) -23 + j*(93) -81 + j*(-90) --136 + j*(-134) --177 + j*(100) -45 + j*(131) -47 + j*(-78) --180 + j*(-56) --181 + j*(211) -100 + j*(286) -260 + j*(47) -89 + j*(-166) --144 + j*(-52) --66 + j*(201) -208 + j*(168) -238 + j*(-100) -21 + j*(-173) --49 + j*(-18) -68 + j*(19) -83 + j*(-82) -11 + j*(-84) -57 + j*(-57) -86 + j*(-197) --140 + j*(-319) --407 + j*(-100) --293 + j*(264) -62 + j*(272) -123 + j*(-11) --105 + j*(-58) --134 + j*(163) -80 + j*(209) -155 + j*(46) -71 + j*(-19) -59 + j*(8) -74 + j*(-35) -5 + j*(-65) --40 + j*(6) -34 + j*(63) -116 + j*(-18) -32 + j*(-153) --170 + j*(-86) --151 + j*(177) -139 + j*(230) -243 + j*(-25) -66 + j*(-116) -74 + j*(6) -221 + j*(-123) -40 + j*(-356) --243 + j*(-229) --197 + j*(-8) --124 + j*(-42) --238 + j*(3) --178 + j*(206) -31 + j*(197) -49 + j*(81) -47 + j*(99) -131 + j*(35) -40 + j*(-76) --39 + j*(45) -158 + j*(82) -191 + j*(-202) --130 + j*(-276) --243 + j*(3) --60 + j*(94) --45 + j*(-2) --97 + j*(67) -23 + j*(94) -18 + j*(-47) --141 + j*(-11) --109 + j*(154) -14 + j*(155) -25 + j*(129) -100 + j*(160) -185 + j*(37) -62 + j*(-59) -3 + j*(79) -188 + j*(106) -227 + j*(-115) -23 + j*(-181) --41 + j*(-38) -45 + j*(1) -62 + j*(-45) -61 + j*(-53) -73 + j*(-99) -13 + j*(-140) --21 + j*(-116) --33 + j*(-151) --171 + j*(-154) --229 + j*(52) --4 + j*(153) -103 + j*(-88) --177 + j*(-197) --326 + j*(118) --32 + j*(326) -197 + j*(108) -51 + j*(-71) --46 + j*(61) -132 + j*(113) -211 + j*(-117) --11 + j*(-269) --214 + j*(-139) --204 + j*(35) --146 + j*(99) --97 + j*(165) -25 + j*(192) -98 + j*(83) -19 + j*(37) -25 + j*(147) -209 + j*(139) -269 + j*(-86) -95 + j*(-238) --99 + j*(-180) --173 + j*(-10) --62 + j*(173) -209 + j*(134) -254 + j*(-197) --91 + j*(-333) --283 + j*(-34) --62 + j*(144) -40 + j*(-25) --119 + j*(-35) --71 + j*(138) -100 + j*(65) -6 + j*(-73) --84 + j*(53) -74 + j*(112) -125 + j*(-59) --14 + j*(-108) --41 + j*(-36) --42 + j*(-70) --158 + j*(-33) --133 + j*(139) -28 + j*(144) -23 + j*(42) --23 + j*(112) -120 + j*(163) -221 + j*(-5) -98 + j*(-145) --37 + j*(-106) --77 + j*(-18) --59 + j*(86) -88 + j*(149) -236 + j*(-10) -112 + j*(-234) --153 + j*(-170) --163 + j*(105) -103 + j*(191) -279 + j*(-30) -151 + j*(-290) --133 + j*(-298) --257 + j*(-75) --139 + j*(90) --11 + j*(49) --37 + j*(-28) --92 + j*(16) --48 + j*(84) -35 + j*(72) -73 + j*(-1) -42 + j*(-86) --60 + j*(-117) --154 + j*(-37) --120 + j*(92) -1 + j*(97) -3 + j*(-5) --102 + j*(25) --38 + j*(170) -160 + j*(95) -95 + j*(-149) --180 + j*(-106) --170 + j*(175) -74 + j*(199) -105 + j*(33) -28 + j*(47) -117 + j*(69) -129 + j*(-82) --30 + j*(-98) --29 + j*(21) -37 + j*(-44) --129 + j*(-81) --194 + j*(180) -102 + j*(317) -298 + j*(81) -173 + j*(-95) -102 + j*(-45) -161 + j*(-87) -81 + j*(-207) --82 + j*(-163) --88 + j*(-7) -56 + j*(30) -127 + j*(-134) --72 + j*(-274) --305 + j*(-72) --132 + j*(230) -192 + j*(95) -82 + j*(-211) --176 + j*(-114) --77 + j*(59) --11 + j*(-83) --235 + j*(-65) --198 + j*(243) -132 + j*(240) -163 + j*(-30) -12 + j*(-59) -31 + j*(-41) --71 + j*(-137) --261 + j*(53) --30 + j*(332) -298 + j*(107) -107 + j*(-206) --142 + j*(-31) -54 + j*(141) -179 + j*(-92) --74 + j*(-200) --170 + j*(34) -23 + j*(98) -40 + j*(-74) --140 + j*(-59) --141 + j*(135) -32 + j*(186) -118 + j*(77) -79 + j*(4) -48 + j*(21) -94 + j*(35) -141 + j*(-46) -68 + j*(-148) --57 + j*(-112) --39 + j*(-5) -47 + j*(-55) --49 + j*(-160) --205 + j*(-52) --132 + j*(129) -9 + j*(98) --30 + j*(44) --6 + j*(156) -211 + j*(107) -202 + j*(-187) --104 + j*(-248) --214 + j*(-8) --91 + j*(83) --95 + j*(62) --86 + j*(191) -116 + j*(219) -183 + j*(42) -83 + j*(14) -173 + j*(68) -264 + j*(-135) -28 + j*(-305) --180 + j*(-119) --67 + j*(59) -47 + j*(-4) -14 + j*(-62) --4 + j*(-70) --54 + j*(-95) --126 + j*(-25) --64 + j*(67) -6 + j*(30) --21 + j*(11) -15 + j*(41) -45 + j*(-38) --64 + j*(-52) --44 + j*(86) -132 + j*(28) -57 + j*(-187) --176 + j*(-132) --165 + j*(63) --75 + j*(78) --80 + j*(124) -78 + j*(195) -228 + j*(-22) --4 + j*(-223) --209 + j*(0) -10 + j*(181) -164 + j*(-49) --78 + j*(-202) --262 + j*(8) --151 + j*(211) -1 + j*(238) -120 + j*(220) -247 + j*(115) -237 + j*(-69) -106 + j*(-139) -52 + j*(-100) -54 + j*(-134) --59 + j*(-187) --202 + j*(-62) --113 + j*(153) -134 + j*(106) -117 + j*(-168) --192 + j*(-185) --261 + j*(141) -46 + j*(265) -199 + j*(12) -1 + j*(-146) --157 + j*(-1) --92 + j*(164) -56 + j*(206) -194 + j*(130) -205 + j*(-42) -58 + j*(-83) -63 + j*(59) -267 + j*(-2) -223 + j*(-295) --92 + j*(-331) --177 + j*(-91) --37 + j*(-39) --65 + j*(-134) --171 + j*(-64) --117 + j*(47) --39 + j*(30) --30 + j*(-4) --33 + j*(-50) --153 + j*(-89) --280 + j*(112) --45 + j*(370) -330 + j*(176) -233 + j*(-250) --165 + j*(-257) --235 + j*(44) --67 + j*(118) --48 + j*(67) --37 + j*(130) -82 + j*(110) -69 + j*(-7) --2 + j*(18) -66 + j*(23) -4 + j*(-115) --230 + j*(-1) --110 + j*(342) -310 + j*(286) -354 + j*(-125) -48 + j*(-234) --42 + j*(-73) -11 + j*(-70) --78 + j*(-76) --73 + j*(71) -103 + j*(57) -84 + j*(-134) --106 + j*(-129) --124 + j*(27) --36 + j*(40) --80 + j*(10) --114 + j*(134) -54 + j*(240) -247 + j*(107) -209 + j*(-124) -13 + j*(-175) --80 + j*(-55) --42 + j*(37) -24 + j*(83) -164 + j*(77) -269 + j*(-146) -24 + j*(-402) --358 + j*(-215) --275 + j*(216) -124 + j*(223) -179 + j*(-100) --56 + j*(-172) --129 + j*(-26) --68 + j*(35) --28 + j*(37) -10 + j*(16) --11 + j*(-30) --37 + j*(6) -37 + j*(-8) --33 + j*(-153) --266 + j*(-46) --162 + j*(266) -182 + j*(187) -122 + j*(-136) --151 + j*(-84) --108 + j*(118) --5 + j*(82) --60 + j*(91) -23 + j*(199) -167 + j*(116) -136 + j*(15) -152 + j*(13) -181 + j*(-128) --24 + j*(-211) --124 + j*(-5) -68 + j*(65) -100 + j*(-121) --51 + j*(-142) --59 + j*(-98) --165 + j*(-158) --366 + j*(54) --148 + j*(388) -223 + j*(250) -158 + j*(-40) -1 + j*(21) -99 + j*(75) -97 + j*(-37) -21 + j*(12) -141 + j*(35) -142 + j*(-153) --66 + j*(-161) --83 + j*(11) -17 + j*(23) -25 + j*(18) -141 + j*(21) -177 + j*(-226) --158 + j*(-329) --309 + j*(18) -6 + j*(153) -71 + j*(-148) --248 + j*(-166) --279 + j*(146) --52 + j*(199) --49 + j*(99) --93 + j*(208) -93 + j*(319) -321 + j*(184) -340 + j*(-88) -131 + j*(-234) --27 + j*(-103) -121 + j*(-9) -181 + j*(-267) --188 + j*(-376) --365 + j*(25) -10 + j*(214) -159 + j*(-136) --173 + j*(-258) --288 + j*(6) --164 + j*(73) --237 + j*(85) --181 + j*(339) -178 + j*(332) -226 + j*(-12) --47 + j*(-44) --12 + j*(185) -211 + j*(103) -128 + j*(-105) --33 + j*(-25) -66 + j*(81) -156 + j*(-54) -0 + j*(-157) --127 + j*(-10) --4 + j*(132) -139 + j*(40) -79 + j*(-74) -23 + j*(-24) -107 + j*(-37) -53 + j*(-196) --178 + j*(-147) --179 + j*(122) -74 + j*(182) -185 + j*(-1) -119 + j*(-127) -28 + j*(-185) --113 + j*(-173) --170 + j*(-17) --35 + j*(49) --16 + j*(-71) --151 + j*(-37) --85 + j*(115) -68 + j*(21) --51 + j*(-130) --218 + j*(-13) --162 + j*(153) --63 + j*(190) -18 + j*(219) -161 + j*(182) -217 + j*(19) -130 + j*(-104) -2 + j*(-137) --141 + j*(-49) --119 + j*(186) -168 + j*(240) -290 + j*(-35) -86 + j*(-157) -57 + j*(-26) -190 + j*(-136) --6 + j*(-339) --279 + j*(-161) --187 + j*(89) --35 + j*(71) --34 + j*(38) -9 + j*(36) --21 + j*(-38) --119 + j*(59) -58 + j*(194) -231 + j*(-33) --16 + j*(-212) --141 + j*(44) -158 + j*(81) -125 + j*(-313) --374 + j*(-289) --446 + j*(250) -17 + j*(442) -265 + j*(146) -147 + j*(-57) -49 + j*(-35) -74 + j*(-35) -49 + j*(-120) --98 + j*(-146) --208 + j*(21) --69 + j*(197) -124 + j*(98) -37 + j*(-71) --103 + j*(37) -32 + j*(169) -162 + j*(35) -54 + j*(-69) --1 + j*(23) -96 + j*(36) -104 + j*(-56) -58 + j*(-69) -78 + j*(-97) -1 + j*(-203) --190 + j*(-150) --219 + j*(67) --55 + j*(164) -41 + j*(95) -35 + j*(70) -101 + j*(92) -202 + j*(-23) -112 + j*(-209) --103 + j*(-188) --135 + j*(-6) --16 + j*(25) --25 + j*(-49) --83 + j*(2) --8 + j*(53) -23 + j*(-26) --57 + j*(-25) --11 + j*(57) -82 + j*(-37) --43 + j*(-152) --170 + j*(-37) --93 + j*(54) --96 + j*(-8) --214 + j*(91) --90 + j*(313) -190 + j*(255) -225 + j*(22) -115 + j*(-39) -119 + j*(-33) -105 + j*(-135) --41 + j*(-175) --135 + j*(-68) --116 + j*(19) --103 + j*(53) --94 + j*(129) -4 + j*(206) -153 + j*(180) -245 + j*(44) -206 + j*(-132) -28 + j*(-211) --133 + j*(-80) --57 + j*(109) -135 + j*(76) -141 + j*(-91) -40 + j*(-116) -51 + j*(-105) -4 + j*(-216) --210 + j*(-176) --216 + j*(76) -6 + j*(90) --40 + j*(-96) --239 + j*(27) --95 + j*(268) -145 + j*(173) -111 + j*(28) -119 + j*(60) -221 + j*(-74) -40 + j*(-259) --171 + j*(-100) --47 + j*(68) -50 + j*(-38) --37 + j*(-72) --7 + j*(-37) --42 + j*(-154) --260 + j*(-73) --182 + j*(211) -93 + j*(139) -1 + j*(-67) --121 + j*(69) -54 + j*(108) --10 + j*(-86) --221 + j*(101) -77 + j*(344) -349 + j*(-26) --51 + j*(-301) --306 + j*(91) -35 + j*(310) -177 + j*(62) -26 + j*(54) -174 + j*(157) -295 + j*(-98) -20 + j*(-240) --98 + j*(-3) -103 + j*(49) -100 + j*(-137) --69 + j*(-115) --49 + j*(13) -22 + j*(-11) --23 + j*(-35) --29 + j*(40) -65 + j*(64) -139 + j*(-15) -112 + j*(-129) -4 + j*(-163) --49 + j*(-100) --20 + j*(-83) --41 + j*(-118) --83 + j*(-96) --82 + j*(-107) --192 + j*(-139) --315 + j*(43) --140 + j*(250) -73 + j*(127) --40 + j*(-17) --107 + j*(146) -124 + j*(192) -196 + j*(-69) --19 + j*(-176) --128 + j*(-65) --133 + j*(-17) --197 + j*(58) --139 + j*(213) -13 + j*(219) -35 + j*(163) -75 + j*(223) -249 + j*(183) -296 + j*(-32) -154 + j*(-146) -62 + j*(-116) -40 + j*(-108) --14 + j*(-113) --75 + j*(-64) --81 + j*(28) -11 + j*(87) -102 + j*(11) -26 + j*(-83) --47 + j*(13) -97 + j*(66) -144 + j*(-139) --105 + j*(-196) --170 + j*(65) -74 + j*(124) -102 + j*(-91) --80 + j*(-80) --29 + j*(71) -97 + j*(2) -42 + j*(-81) -35 + j*(-62) -48 + j*(-177) --178 + j*(-238) --325 + j*(26) --100 + j*(229) -79 + j*(75) --45 + j*(-35) --101 + j*(106) -62 + j*(166) -164 + j*(25) -97 + j*(-110) --28 + j*(-144) --144 + j*(-75) --161 + j*(84) --7 + j*(173) -120 + j*(52) -18 + j*(-78) --114 + j*(42) -45 + j*(204) -273 + j*(22) -107 + j*(-272) --217 + j*(-142) --112 + j*(176) -195 + j*(71) -88 + j*(-234) --211 + j*(-156) --177 + j*(99) --6 + j*(92) --29 + j*(5) --69 + j*(59) --11 + j*(93) -20 + j*(63) -31 + j*(49) -30 + j*(6) --49 + j*(11) --37 + j*(144) -149 + j*(153) -198 + j*(-51) -23 + j*(-128) --43 + j*(4) -64 + j*(35) -70 + j*(-76) --52 + j*(-81) --86 + j*(45) -15 + j*(118) -117 + j*(75) -143 + j*(-13) -119 + j*(-71) -87 + j*(-121) -4 + j*(-158) --98 + j*(-84) --44 + j*(57) -132 + j*(25) -141 + j*(-175) --33 + j*(-253) --145 + j*(-178) --187 + j*(-118) --250 + j*(-28) --211 + j*(132) --40 + j*(179) -53 + j*(59) --20 + j*(-36) --122 + j*(10) --110 + j*(148) -61 + j*(212) -224 + j*(52) -129 + j*(-190) --135 + j*(-187) --214 + j*(35) --81 + j*(148) -1 + j*(98) --6 + j*(98) -69 + j*(136) -181 + j*(28) -91 + j*(-155) --130 + j*(-107) --113 + j*(127) -132 + j*(112) -103 + j*(-163) --225 + j*(-134) --235 + j*(238) -124 + j*(314) -231 + j*(42) -78 + j*(-9) -156 + j*(80) -275 + j*(-119) -40 + j*(-315) --192 + j*(-129) --70 + j*(52) -16 + j*(-64) --165 + j*(-95) --232 + j*(161) -25 + j*(338) -308 + j*(185) -317 + j*(-112) -103 + j*(-245) --50 + j*(-148) --11 + j*(-56) -17 + j*(-116) --97 + j*(-125) --129 + j*(23) -25 + j*(85) -115 + j*(-62) --6 + j*(-184) --159 + j*(-110) --139 + j*(45) --1 + j*(64) -28 + j*(-65) --100 + j*(-98) --138 + j*(18) --51 + j*(27) --122 + j*(-42) --230 + j*(123) --16 + j*(313) -245 + j*(122) -118 + j*(-151) --115 + j*(-88) --102 + j*(78) --15 + j*(105) -45 + j*(103) -127 + j*(21) -37 + j*(-133) --170 + j*(-50) --119 + j*(180) -85 + j*(175) -108 + j*(61) -115 + j*(46) -151 + j*(-66) --31 + j*(-154) --152 + j*(68) -88 + j*(200) -204 + j*(-35) --8 + j*(-97) -10 + j*(114) -246 + j*(33) -162 + j*(-222) --52 + j*(-168) --8 + j*(-47) -22 + j*(-113) --56 + j*(-87) -23 + j*(-35) -49 + j*(-194) --185 + j*(-232) --262 + j*(21) --47 + j*(101) -8 + j*(-89) --191 + j*(-145) --322 + j*(28) --266 + j*(245) --43 + j*(359) -177 + j*(213) -93 + j*(-14) --114 + j*(91) -46 + j*(342) -381 + j*(202) -356 + j*(-164) -76 + j*(-260) --67 + j*(-126) --42 + j*(-6) -54 + j*(9) -84 + j*(-112) --93 + j*(-175) --216 + j*(41) --4 + j*(220) -187 + j*(48) -62 + j*(-99) --8 + j*(18) -151 + j*(32) -170 + j*(-167) -1 + j*(-237) --81 + j*(-171) --116 + j*(-170) --235 + j*(-134) --296 + j*(37) --192 + j*(194) --21 + j*(214) -74 + j*(98) --1 + j*(-1) --93 + j*(92) -38 + j*(225) -244 + j*(106) -206 + j*(-135) -13 + j*(-202) --122 + j*(-124) --175 + j*(12) --77 + j*(171) -138 + j*(122) -132 + j*(-113) --93 + j*(-131) --113 + j*(52) -14 + j*(35) --81 + j*(-54) --184 + j*(119) -7 + j*(270) -177 + j*(148) -148 + j*(47) -192 + j*(47) -250 + j*(-116) -63 + j*(-264) --123 + j*(-127) --39 + j*(22) -52 + j*(-51) --25 + j*(-103) --47 + j*(-40) --6 + j*(-68) --97 + j*(-120) --204 + j*(-2) --122 + j*(153) -33 + j*(144) -76 + j*(43) -42 + j*(-7) -21 + j*(-5) -32 + j*(-12) -24 + j*(-70) --91 + j*(-107) --226 + j*(40) --106 + j*(296) -238 + j*(284) -373 + j*(-71) -105 + j*(-325) --190 + j*(-192) --182 + j*(65) --12 + j*(129) -65 + j*(48) -39 + j*(-4) -18 + j*(13) -54 + j*(33) -107 + j*(-6) -110 + j*(-91) -38 + j*(-165) --86 + j*(-168) --182 + j*(-47) --103 + j*(130) -128 + j*(115) -190 + j*(-144) --47 + j*(-298) --258 + j*(-156) --246 + j*(28) --178 + j*(105) --101 + j*(175) -53 + j*(149) -76 + j*(-33) --113 + j*(-80) --179 + j*(104) --24 + j*(184) -38 + j*(68) --64 + j*(44) --83 + j*(166) -38 + j*(235) -155 + j*(177) -173 + j*(84) -158 + j*(74) -257 + j*(64) -337 + j*(-165) -70 + j*(-406) --300 + j*(-202) --197 + j*(201) -158 + j*(170) -151 + j*(-98) --24 + j*(-82) -13 + j*(11) -29 + j*(-41) --23 + j*(28) -142 + j*(89) -243 + j*(-152) --11 + j*(-301) --160 + j*(-95) --9 + j*(-13) --18 + j*(-156) --180 + j*(-100) --137 + j*(49) --59 + j*(32) --93 + j*(57) -9 + j*(139) -139 + j*(30) -85 + j*(-95) -49 + j*(-113) --1 + j*(-236) --292 + j*(-232) --390 + j*(163) -18 + j*(347) -232 + j*(-16) --69 + j*(-199) --178 + j*(31) --9 + j*(29) --153 + j*(-123) --350 + j*(132) --78 + j*(395) -177 + j*(175) --3 + j*(17) --54 + j*(233) -233 + j*(250) -274 + j*(-47) -47 + j*(-99) -62 + j*(39) -161 + j*(-92) --80 + j*(-226) --301 + j*(77) --18 + j*(404) -385 + j*(230) -369 + j*(-156) -106 + j*(-264) --22 + j*(-159) --18 + j*(-98) --25 + j*(-91) --62 + j*(-67) --71 + j*(3) -14 + j*(64) -128 + j*(-19) -71 + j*(-185) --119 + j*(-175) --159 + j*(-13) --60 + j*(39) --55 + j*(-1) --75 + j*(60) -33 + j*(105) -115 + j*(1) -66 + j*(-100) -3 + j*(-122) --59 + j*(-150) --186 + j*(-126) --264 + j*(36) --168 + j*(209) -22 + j*(231) -126 + j*(107) -83 + j*(4) -36 + j*(27) -107 + j*(28) -112 + j*(-110) --60 + j*(-147) --120 + j*(21) -26 + j*(76) -58 + j*(-45) --23 + j*(-40) -44 + j*(-8) -48 + j*(-170) --195 + j*(-199) --287 + j*(54) --105 + j*(174) --40 + j*(91) --74 + j*(122) -21 + j*(158) -40 + j*(59) --60 + j*(115) -76 + j*(275) -334 + j*(137) -289 + j*(-160) -68 + j*(-228) --31 + j*(-156) --88 + j*(-124) --161 + j*(-33) --124 + j*(107) -8 + j*(153) -107 + j*(76) -85 + j*(-28) --11 + j*(-13) -36 + j*(100) -209 + j*(28) -150 + j*(-202) --91 + j*(-184) --93 + j*(16) -47 + j*(-1) --6 + j*(-98) --74 + j*(-21) -4 + j*(15) -9 + j*(-45) --18 + j*(-18) -45 + j*(-42) --28 + j*(-154) --188 + j*(-57) --95 + j*(119) -54 + j*(37) --26 + j*(-59) --64 + j*(36) -48 + j*(21) -4 + j*(-108) --123 + j*(-68) --115 + j*(13) --122 + j*(18) --150 + j*(101) --64 + j*(182) -11 + j*(168) -74 + j*(197) -255 + j*(128) -258 + j*(-156) --20 + j*(-245) --132 + j*(-64) --83 + j*(-25) --188 + j*(30) --97 + j*(302) -292 + j*(246) -298 + j*(-159) --21 + j*(-179) -32 + j*(19) -153 + j*(-161) --119 + j*(-269) --227 + j*(11) -1 + j*(71) --40 + j*(-97) --175 + j*(52) -53 + j*(170) -153 + j*(-105) --145 + j*(-195) --250 + j*(85) --49 + j*(207) -48 + j*(129) -20 + j*(-16) --153 + j*(39) --67 + j*(248) -168 + j*(204) -190 + j*(6) -79 + j*(-42) -55 + j*(11) -116 + j*(11) -151 + j*(-91) -37 + j*(-217) --189 + j*(-141) --180 + j*(150) -139 + j*(216) -272 + j*(-98) -0 + j*(-273) --162 + j*(-72) --13 + j*(18) --18 + j*(-144) --253 + j*(-80) --201 + j*(224) -119 + j*(223) -158 + j*(-62) --76 + j*(-111) --123 + j*(72) --8 + j*(115) -5 + j*(85) -42 + j*(146) -187 + j*(103) -190 + j*(-75) -51 + j*(-117) -18 + j*(-45) -43 + j*(-53) -4 + j*(-48) -48 + j*(8) -132 + j*(-81) -28 + j*(-197) --75 + j*(-110) -22 + j*(-79) --21 + j*(-257) --312 + j*(-221) --363 + j*(127) --65 + j*(267) -102 + j*(74) -8 + j*(-53) --57 + j*(-21) --49 + j*(-23) --98 + j*(-45) --168 + j*(1) --192 + j*(103) --134 + j*(218) -10 + j*(260) -124 + j*(185) -151 + j*(85) -132 + j*(1) -42 + j*(-52) --50 + j*(34) -49 + j*(156) -209 + j*(53) -132 + j*(-117) -2 + j*(-72) -53 + j*(-21) -35 + j*(-124) --127 + j*(-79) --94 + j*(112) -71 + j*(101) -65 + j*(6) -58 + j*(45) -162 + j*(-21) -55 + j*(-196) --175 + j*(-70) --47 + j*(199) -252 + j*(92) -190 + j*(-209) --69 + j*(-199) --71 + j*(-8) -73 + j*(-34) -11 + j*(-181) --168 + j*(-110) --112 + j*(105) -133 + j*(71) -139 + j*(-204) --138 + j*(-275) --276 + j*(-60) --179 + j*(93) --94 + j*(119) -18 + j*(148) -162 + j*(6) -26 + j*(-228) --247 + j*(-132) --196 + j*(110) --56 + j*(52) --201 + j*(25) --186 + j*(303) -185 + j*(322) -255 + j*(-55) --76 + j*(-139) --141 + j*(135) -88 + j*(190) -140 + j*(19) -35 + j*(-28) --6 + j*(30) -34 + j*(95) -163 + j*(86) -219 + j*(-117) --15 + j*(-264) --230 + j*(-56) --86 + j*(169) -83 + j*(84) -21 + j*(7) -28 + j*(96) -162 + j*(54) -146 + j*(-94) -45 + j*(-119) -13 + j*(-106) --49 + j*(-112) --103 + j*(-21) --24 + j*(58) -58 + j*(6) -44 + j*(-64) --5 + j*(-103) --108 + j*(-93) --155 + j*(63) -35 + j*(171) -190 + j*(-23) -7 + j*(-206) --175 + j*(-45) --35 + j*(121) -113 + j*(-3) -18 + j*(-146) --119 + j*(-103) --148 + j*(11) --88 + j*(97) -18 + j*(88) -26 + j*(-2) --47 + j*(23) -50 + j*(112) -197 + j*(-47) -23 + j*(-272) --256 + j*(-141) --197 + j*(119) --28 + j*(103) --75 + j*(49) --61 + j*(182) -146 + j*(168) -159 + j*(-66) --41 + j*(-97) --52 + j*(81) -131 + j*(78) -152 + j*(-101) --6 + j*(-171) --116 + j*(-80) --110 + j*(36) --23 + j*(101) -86 + j*(69) -116 + j*(-40) -59 + j*(-113) --4 + j*(-137) --81 + j*(-152) --188 + j*(-98) --225 + j*(40) --157 + j*(156) --58 + j*(203) -49 + j*(203) -142 + j*(134) -159 + j*(27) -109 + j*(-42) -33 + j*(-64) --49 + j*(4) -13 + j*(147) -227 + j*(116) -262 + j*(-137) -35 + j*(-221) --35 + j*(-57) -105 + j*(-54) -57 + j*(-218) --124 + j*(-179) --112 + j*(-45) --62 + j*(-72) --150 + j*(-71) --165 + j*(53) --93 + j*(107) --51 + j*(159) -119 + j*(214) -309 + j*(1) -148 + j*(-280) --118 + j*(-215) --103 + j*(-68) --106 + j*(-115) --245 + j*(-18) --124 + j*(192) -93 + j*(70) --49 + j*(-119) --227 + j*(47) --80 + j*(221) -50 + j*(139) -16 + j*(105) -64 + j*(148) -132 + j*(102) -154 + j*(76) -253 + j*(1) -211 + j*(-228) --62 + j*(-268) --141 + j*(-52) --21 + j*(-23) --99 + j*(-81) --146 + j*(102) -98 + j*(163) -176 + j*(-89) --30 + j*(-168) --74 + j*(-58) --72 + j*(-105) --255 + j*(-44) --206 + j*(249) -106 + j*(258) -140 + j*(19) -6 + j*(35) -111 + j*(107) -173 + j*(-62) -7 + j*(-121) --20 + j*(1) -59 + j*(-44) --64 + j*(-100) --124 + j*(90) -105 + j*(177) -235 + j*(-37) -90 + j*(-192) --28 + j*(-144) --42 + j*(-128) --148 + j*(-137) --256 + j*(38) --103 + j*(261) -194 + j*(200) -233 + j*(-95) --8 + j*(-198) --115 + j*(-16) -40 + j*(62) -106 + j*(-97) --47 + j*(-189) --173 + j*(-98) --190 + j*(20) --149 + j*(123) --37 + j*(182) -63 + j*(129) -74 + j*(73) -105 + j*(53) -122 + j*(-39) -19 + j*(-87) --16 + j*(11) -98 + j*(8) -78 + j*(-145) --92 + j*(-151) --136 + j*(-19) --94 + j*(37) --70 + j*(81) -18 + j*(103) -47 + j*(9) --56 + j*(27) -33 + j*(182) -274 + j*(57) -168 + j*(-253) --151 + j*(-201) --143 + j*(74) -79 + j*(80) -96 + j*(-104) --49 + j*(-161) --158 + j*(-77) --153 + j*(47) --65 + j*(85) --58 + j*(42) --104 + j*(119) -37 + j*(215) -175 + j*(63) -37 + j*(-49) -5 + j*(101) -208 + j*(50) -102 + j*(-205) --168 + j*(-50) -47 + j*(210) -306 + j*(-73) --16 + j*(-332) --255 + j*(-18) -41 + j*(160) -139 + j*(-130) --158 + j*(-171) --180 + j*(115) -55 + j*(134) -56 + j*(-25) --40 + j*(18) -54 + j*(101) -173 + j*(-6) -116 + j*(-182) --86 + j*(-226) --232 + j*(-57) --132 + j*(143) -54 + j*(100) -23 + j*(-40) --83 + j*(20) -1 + j*(123) -117 + j*(54) -103 + j*(-50) -57 + j*(-96) --11 + j*(-141) --128 + j*(-109) --163 + j*(13) --107 + j*(88) --53 + j*(115) -16 + j*(123) -62 + j*(72) -40 + j*(47) -73 + j*(71) -129 + j*(-10) -32 + j*(-91) --40 + j*(18) -92 + j*(69) -134 + j*(-86) --20 + j*(-116) --22 + j*(19) -113 + j*(-21) -64 + j*(-169) --74 + j*(-158) --113 + j*(-92) --147 + j*(-40) --122 + j*(71) -29 + j*(62) -12 + j*(-122) --220 + j*(-116) --272 + j*(134) --90 + j*(245) --1 + j*(192) -25 + j*(218) -171 + j*(227) -279 + j*(64) -198 + j*(-95) -87 + j*(-100) -73 + j*(-67) -80 + j*(-100) -35 + j*(-149) --53 + j*(-163) --153 + j*(-111) --209 + j*(27) --129 + j*(186) -68 + j*(223) -205 + j*(86) -179 + j*(-74) -88 + j*(-138) -5 + j*(-157) --96 + j*(-119) --115 + j*(1) --16 + j*(38) --15 + j*(-49) --125 + j*(6) --32 + j*(174) -199 + j*(79) -140 + j*(-194) --129 + j*(-188) --168 + j*(26) --37 + j*(71) --35 + j*(20) --45 + j*(83) -76 + j*(84) -86 + j*(-76) --113 + j*(-103) --179 + j*(133) -62 + j*(269) -273 + j*(88) -204 + j*(-132) -66 + j*(-167) -2 + j*(-162) --103 + j*(-144) --148 + j*(13) -28 + j*(86) -103 + j*(-114) --116 + j*(-188) --182 + j*(15) --18 + j*(18) --134 + j*(-136) --347 + j*(89) --95 + j*(383) -220 + j*(180) -69 + j*(-60) --48 + j*(91) -146 + j*(103) -101 + j*(-139) --162 + j*(-80) --118 + j*(158) -24 + j*(144) --9 + j*(153) -144 + j*(295) -445 + j*(102) -343 + j*(-304) --41 + j*(-339) --161 + j*(-82) --35 + j*(47) -82 + j*(1) -88 + j*(-138) --106 + j*(-212) --285 + j*(14) --85 + j*(303) -262 + j*(192) -267 + j*(-119) -84 + j*(-187) -59 + j*(-170) --18 + j*(-281) --279 + j*(-235) --345 + j*(93) --56 + j*(264) -149 + j*(54) --6 + j*(-124) --141 + j*(19) -14 + j*(121) -86 + j*(-53) --107 + j*(-88) --104 + j*(133) -148 + j*(91) -79 + j*(-190) --215 + j*(-110) --141 + j*(163) -71 + j*(98) --9 + j*(-30) --50 + j*(76) -74 + j*(47) --21 + j*(-69) --111 + j*(97) -124 + j*(161) -175 + j*(-124) --117 + j*(-168) --140 + j*(79) -18 + j*(42) --129 + j*(-30) --170 + j*(247) -187 + j*(317) -292 + j*(-23) -37 + j*(-107) -30 + j*(71) -175 + j*(-1) -69 + j*(-127) --26 + j*(-14) -93 + j*(53) -172 + j*(-49) -153 + j*(-153) -76 + j*(-268) --137 + j*(-300) --285 + j*(-99) --179 + j*(86) --56 + j*(67) --50 + j*(33) --41 + j*(37) --47 + j*(40) --22 + j*(98) -101 + j*(63) -71 + j*(-103) --99 + j*(-73) --39 + j*(54) -16 + j*(-78) --238 + j*(-69) --216 + j*(317) -238 + j*(336) -301 + j*(-74) -30 + j*(-109) -119 + j*(-5) -102 + j*(-274) --336 + j*(-198) --234 + j*(338) -317 + j*(203) -107 + j*(-310) --373 + j*(9) -39 + j*(494) -548 + j*(83) -259 + j*(-392) --59 + j*(-276) --50 + j*(-222) --245 + j*(-243) --345 + j*(76) --46 + j*(217) -41 + j*(0) --101 + j*(28) -41 + j*(107) -47 + j*(-132) --296 + j*(-61) --186 + j*(387) -322 + j*(310) -317 + j*(-164) --23 + j*(-210) --63 + j*(-51) --68 + j*(-73) --175 + j*(40) --20 + j*(210) -158 + j*(66) -35 + j*(-66) --25 + j*(49) -91 + j*(58) -83 + j*(-30) -75 + j*(-8) -147 + j*(-103) --15 + j*(-257) --227 + j*(-94) --94 + j*(96) -3 + j*(-42) --209 + j*(-49) --199 + j*(257) -140 + j*(306) -250 + j*(40) -117 + j*(-65) -97 + j*(-48) -59 + j*(-125) --77 + j*(-87) --37 + j*(62) -100 + j*(11) -37 + j*(-114) --59 + j*(-43) -25 + j*(4) -25 + j*(-114) --153 + j*(-93) --145 + j*(137) -109 + j*(171) -191 + j*(-75) --13 + j*(-193) --144 + j*(-52) --71 + j*(59) --11 + j*(46) -20 + j*(59) -115 + j*(11) -86 + j*(-164) --141 + j*(-180) --206 + j*(53) --4 + j*(141) -72 + j*(-33) --84 + j*(-98) --161 + j*(37) --96 + j*(133) --21 + j*(173) -110 + j*(175) -214 + j*(13) -74 + j*(-158) --111 + j*(-55) --28 + j*(112) -115 + j*(41) -57 + j*(-75) --24 + j*(-36) --1 + j*(-3) --20 + j*(-16) --31 + j*(53) -78 + j*(77) -124 + j*(-49) -11 + j*(-101) --12 + j*(-10) -84 + j*(-37) -29 + j*(-175) --149 + j*(-140) --162 + j*(32) --39 + j*(63) --34 + j*(-16) --105 + j*(19) --59 + j*(109) -41 + j*(71) -3 + j*(-23) --98 + j*(30) --42 + j*(162) -121 + j*(127) -112 + j*(-46) --64 + j*(-49) --78 + j*(147) -136 + j*(196) -232 + j*(0) -93 + j*(-115) --5 + j*(-24) -59 + j*(53) -144 + j*(33) -218 + j*(-44) -221 + j*(-222) -6 + j*(-361) --238 + j*(-199) --153 + j*(69) -88 + j*(24) -55 + j*(-197) --150 + j*(-198) --190 + j*(-41) --102 + j*(-2) --101 + j*(-59) --194 + j*(-53) --261 + j*(78) --156 + j*(254) -87 + j*(235) -144 + j*(-18) --100 + j*(-113) --231 + j*(132) --11 + j*(312) -197 + j*(161) -122 + j*(-5) -43 + j*(53) -148 + j*(74) -173 + j*(-95) --18 + j*(-148) --86 + j*(41) -116 + j*(92) -151 + j*(-148) --134 + j*(-187) --187 + j*(127) -143 + j*(188) -202 + j*(-142) --109 + j*(-194) --141 + j*(74) -67 + j*(52) --37 + j*(-107) --177 + j*(85) -66 + j*(231) -214 + j*(-20) --19 + j*(-139) --97 + j*(74) -100 + j*(126) -143 + j*(-30) -59 + j*(-60) -67 + j*(-48) -49 + j*(-99) --6 + j*(-85) -2 + j*(-83) --78 + j*(-118) --170 + j*(35) -22 + j*(202) -261 + j*(16) -144 + j*(-269) --115 + j*(-267) --222 + j*(-120) --230 + j*(24) --117 + j*(153) -61 + j*(76) --21 + j*(-107) --218 + j*(6) --86 + j*(230) -141 + j*(103) -21 + j*(-98) --153 + j*(20) --58 + j*(168) -37 + j*(133) -56 + j*(142) -192 + j*(128) -230 + j*(-85) -17 + j*(-165) --42 + j*(20) -144 + j*(10) -78 + j*(-226) --221 + j*(-146) --165 + j*(190) -173 + j*(174) -194 + j*(-137) --57 + j*(-189) --112 + j*(-10) -4 + j*(12) --13 + j*(-78) --116 + j*(-51) --128 + j*(61) --35 + j*(141) -119 + j*(104) -158 + j*(-125) --125 + j*(-265) --395 + j*(30) --168 + j*(416) -249 + j*(329) -288 + j*(0) -127 + j*(-76) -122 + j*(-61) -76 + j*(-166) --107 + j*(-134) --115 + j*(67) -70 + j*(103) -136 + j*(-47) -35 + j*(-147) --89 + j*(-117) --135 + j*(0) --57 + j*(94) -35 + j*(58) -16 + j*(11) -26 + j*(54) -121 + j*(8) -77 + j*(-132) --66 + j*(-115) --62 + j*(-21) --44 + j*(-54) --147 + j*(-11) --90 + j*(163) -119 + j*(127) -98 + j*(-64) --51 + j*(-28) -23 + j*(93) -136 + j*(-2) -59 + j*(-98) -25 + j*(-46) -92 + j*(-109) --35 + j*(-244) --247 + j*(-124) --176 + j*(107) -21 + j*(59) --58 + j*(-110) --253 + j*(-2) --168 + j*(241) -71 + j*(222) -96 + j*(59) -28 + j*(57) -93 + j*(68) -86 + j*(-60) --78 + j*(-46) --54 + j*(137) -134 + j*(111) -105 + j*(-52) --15 + j*(-2) -73 + j*(86) -153 + j*(-13) -109 + j*(-70) -141 + j*(-113) -49 + j*(-303) --291 + j*(-239) --296 + j*(175) -111 + j*(217) -139 + j*(-158) --216 + j*(-148) --193 + j*(179) -64 + j*(148) --6 + j*(-11) --98 + j*(140) -112 + j*(226) -215 + j*(31) -93 + j*(-42) -110 + j*(34) -212 + j*(-61) -122 + j*(-230) --73 + j*(-220) --151 + j*(-72) --80 + j*(49) -42 + j*(33) -48 + j*(-71) --34 + j*(-74) --5 + j*(-15) -45 + j*(-105) --96 + j*(-188) --226 + j*(-47) --139 + j*(88) --63 + j*(54) --95 + j*(61) --36 + j*(117) -24 + j*(41) --85 + j*(0) --132 + j*(162) -52 + j*(274) -237 + j*(158) -254 + j*(-29) -160 + j*(-160) -0 + j*(-185) --93 + j*(-59) -9 + j*(45) -118 + j*(-73) --11 + j*(-226) --217 + j*(-146) --233 + j*(57) --114 + j*(142) --49 + j*(125) --33 + j*(145) -49 + j*(185) -175 + j*(114) -163 + j*(-51) -4 + j*(-78) --24 + j*(78) -165 + j*(107) -232 + j*(-113) -29 + j*(-233) --103 + j*(-90) --6 + j*(2) -33 + j*(-94) --83 + j*(-117) --119 + j*(-3) --40 + j*(37) --17 + j*(-3) --37 + j*(-3) --30 + j*(6) --42 + j*(1) --52 + j*(42) -6 + j*(63) -35 + j*(1) --27 + j*(-25) --57 + j*(37) --6 + j*(85) -65 + j*(64) -93 + j*(-26) --6 + j*(-112) --162 + j*(-6) --62 + j*(223) -232 + j*(156) -214 + j*(-170) --101 + j*(-198) --153 + j*(74) -57 + j*(127) -87 + j*(-12) -13 + j*(11) -103 + j*(54) -158 + j*(-85) -23 + j*(-167) --68 + j*(-73) --16 + j*(6) -66 + j*(-13) -106 + j*(-112) -16 + j*(-253) --206 + j*(-235) --287 + j*(-20) --161 + j*(94) --115 + j*(45) --179 + j*(110) --66 + j*(265) -177 + j*(206) -229 + j*(-56) -29 + j*(-212) --180 + j*(-122) --211 + j*(67) --111 + j*(175) --7 + j*(196) -98 + j*(174) -173 + j*(52) -76 + j*(-78) --70 + j*(-5) --7 + j*(144) -130 + j*(100) -120 + j*(18) -137 + j*(25) -191 + j*(-89) -27 + j*(-209) --123 + j*(-37) -49 + j*(95) -144 + j*(-89) --53 + j*(-139) --40 + j*(62) -180 + j*(-23) -50 + j*(-293) --267 + j*(-175) --211 + j*(141) -48 + j*(148) -93 + j*(-32) --21 + j*(-88) --88 + j*(-21) --52 + j*(52) -20 + j*(28) --15 + j*(-39) --94 + j*(19) --23 + j*(121) -88 + j*(68) -71 + j*(-22) -28 + j*(-31) -0 + j*(-36) --36 + j*(21) -67 + j*(81) -156 + j*(-72) --31 + j*(-177) --110 + j*(28) -133 + j*(40) -74 + j*(-280) --330 + j*(-195) --272 + j*(250) -146 + j*(238) -168 + j*(-88) --37 + j*(-124) --72 + j*(-48) --106 + j*(-19) --66 + j*(86) -80 + j*(-11) --115 + j*(-216) --410 + j*(63) --127 + j*(443) -249 + j*(223) -89 + j*(-33) -8 + j*(133) -240 + j*(65) -91 + j*(-233) --233 + j*(-70) --98 + j*(220) -87 + j*(124) -2 + j*(88) -93 + j*(220) -280 + j*(86) -178 + j*(-92) -82 + j*(-25) -150 + j*(-11) -131 + j*(-62) -169 + j*(-24) -284 + j*(-177) -86 + j*(-409) --194 + j*(-261) --110 + j*(-54) --40 + j*(-146) --190 + j*(-113) --112 + j*(75) -57 + j*(-34) --89 + j*(-157) --156 + j*(21) -44 + j*(25) --8 + j*(-208) --265 + j*(-150) --250 + j*(71) --143 + j*(82) --176 + j*(101) --104 + j*(218) -48 + j*(175) -52 + j*(69) -42 + j*(62) -76 + j*(-13) --42 + j*(-117) --218 + j*(-21) --216 + j*(183) --65 + j*(296) -95 + j*(268) -155 + j*(155) -118 + j*(115) -166 + j*(144) -257 + j*(42) -170 + j*(-81) -105 + j*(-21) -202 + j*(-64) -71 + j*(-257) --216 + j*(-83) --33 + j*(272) -344 + j*(103) -203 + j*(-236) --35 + j*(-91) -180 + j*(45) -285 + j*(-255) --16 + j*(-395) --144 + j*(-194) --54 + j*(-185) --204 + j*(-263) --358 + j*(-25) --134 + j*(192) -87 + j*(17) --61 + j*(-190) --274 + j*(-67) --202 + j*(146) --24 + j*(114) --71 + j*(-14) --197 + j*(93) --50 + j*(267) -165 + j*(129) -54 + j*(-76) --102 + j*(35) -39 + j*(137) -101 + j*(-47) --115 + j*(-85) --144 + j*(139) -53 + j*(161) -45 + j*(17) --57 + j*(78) -47 + j*(170) -136 + j*(62) -45 + j*(-3) -9 + j*(91) -122 + j*(133) -210 + j*(30) -152 + j*(-102) -6 + j*(-80) -28 + j*(83) -249 + j*(54) -253 + j*(-223) --12 + j*(-285) --82 + j*(-117) --32 + j*(-133) --198 + j*(-104) --148 + j*(222) -318 + j*(199) -364 + j*(-360) --198 + j*(-505) --407 + j*(-36) --81 + j*(146) -15 + j*(-82) --185 + j*(-115) --231 + j*(62) --135 + j*(154) --32 + j*(180) -85 + j*(121) -83 + j*(-10) --6 + j*(-30) --6 + j*(5) --22 + j*(-37) --99 + j*(20) --8 + j*(119) -107 + j*(-13) --62 + j*(-148) --233 + j*(29) --110 + j*(229) -69 + j*(205) -139 + j*(107) -148 + j*(-12) -15 + j*(-99) --117 + j*(44) -35 + j*(213) -230 + j*(81) -153 + j*(-101) -45 + j*(-81) -46 + j*(-70) --18 + j*(-79) --33 + j*(27) -107 + j*(33) -115 + j*(-139) --54 + j*(-181) --138 + j*(-85) --167 + j*(-8) --170 + j*(141) -24 + j*(254) -207 + j*(93) -97 + j*(-66) -15 + j*(45) -188 + j*(88) -281 + j*(-124) -144 + j*(-306) --56 + j*(-351) --270 + j*(-260) --339 + j*(7) --134 + j*(148) --58 + j*(4) --243 + j*(64) --98 + j*(387) -372 + j*(268) -358 + j*(-269) --140 + j*(-374) --326 + j*(1) --108 + j*(205) -54 + j*(144) -113 + j*(67) -145 + j*(-55) -17 + j*(-186) --179 + j*(-106) --173 + j*(105) -6 + j*(173) -120 + j*(52) -62 + j*(-79) --54 + j*(-76) --91 + j*(-2) --81 + j*(37) --84 + j*(86) --18 + j*(156) -94 + j*(109) -66 + j*(1) --30 + j*(43) -35 + j*(156) -177 + j*(122) -224 + j*(-8) -184 + j*(-121) -73 + j*(-189) --50 + j*(-130) --21 + j*(-18) -64 + j*(-62) -3 + j*(-136) --38 + j*(-88) -1 + j*(-141) --177 + j*(-245) --417 + j*(-3) --223 + j*(356) -144 + j*(274) -133 + j*(2) --23 + j*(29) -54 + j*(130) -156 + j*(40) -117 + j*(-54) -80 + j*(-83) -22 + j*(-125) --69 + j*(-81) --42 + j*(8) -26 + j*(-35) --51 + j*(-103) --154 + j*(-21) --129 + j*(120) --1 + j*(198) -175 + j*(153) -254 + j*(-54) -97 + j*(-231) --97 + j*(-167) --103 + j*(-42) --78 + j*(-31) --126 + j*(18) --64 + j*(139) -108 + j*(125) -172 + j*(-43) -69 + j*(-180) --100 + j*(-182) --194 + j*(-36) --94 + j*(103) -51 + j*(16) --61 + j*(-156) --307 + j*(-35) --250 + j*(295) -100 + j*(351) -247 + j*(54) -11 + j*(-116) --156 + j*(104) -71 + j*(301) -324 + j*(105) -209 + j*(-163) -2 + j*(-124) -25 + j*(-20) -53 + j*(-74) --29 + j*(-71) --11 + j*(-1) -18 + j*(-50) --83 + j*(-41) --61 + j*(117) -119 + j*(110) -141 + j*(-40) -78 + j*(-63) -103 + j*(-100) --4 + j*(-199) --146 + j*(-67) -11 + j*(60) -96 + j*(-160) --206 + j*(-229) --296 + j*(124) -49 + j*(225) -127 + j*(-81) --148 + j*(-121) --178 + j*(133) -12 + j*(196) -109 + j*(129) -199 + j*(47) -197 + j*(-168) --59 + j*(-260) --194 + j*(-43) --33 + j*(56) --24 + j*(-89) --209 + j*(-33) --154 + j*(204) -91 + j*(205) -155 + j*(6) -28 + j*(-95) --91 + j*(-32) --73 + j*(102) -71 + j*(110) -86 + j*(-47) --96 + j*(-49) --97 + j*(175) -162 + j*(208) -236 + j*(-28) -86 + j*(-104) -83 + j*(-31) -144 + j*(-143) --41 + j*(-261) --227 + j*(-84) --100 + j*(122) -78 + j*(37) -5 + j*(-104) --107 + j*(-34) --36 + j*(46) --1 + j*(-52) --163 + j*(-68) --221 + j*(161) -13 + j*(306) -222 + j*(154) -190 + j*(-35) -95 + j*(-87) -23 + j*(-92) --39 + j*(-25) -51 + j*(57) -160 + j*(-88) --40 + j*(-257) --277 + j*(-37) --72 + j*(240) -201 + j*(61) -33 + j*(-181) --167 + j*(-4) -23 + j*(164) -177 + j*(-35) --9 + j*(-182) --146 + j*(-37) --55 + j*(64) --23 + j*(12) --80 + j*(59) -23 + j*(174) -213 + j*(78) -189 + j*(-164) --45 + j*(-227) --160 + j*(-63) --71 + j*(49) -1 + j*(5) --30 + j*(-38) --71 + j*(-27) --113 + j*(4) --131 + j*(110) -4 + j*(221) -197 + j*(117) -167 + j*(-107) --25 + j*(-143) --84 + j*(-18) --26 + j*(17) --46 + j*(-12) --90 + j*(59) --5 + j*(156) -136 + j*(110) -164 + j*(-22) -103 + j*(-94) -66 + j*(-124) --8 + j*(-197) --194 + j*(-173) --287 + j*(54) --124 + j*(237) -52 + j*(200) -112 + j*(145) -231 + j*(81) -262 + j*(-181) --52 + j*(-349) --326 + j*(-77) --149 + j*(221) -91 + j*(129) -30 + j*(-11) --32 + j*(62) -56 + j*(96) -81 + j*(35) -79 + j*(51) -174 + j*(16) -170 + j*(-146) --2 + j*(-214) --122 + j*(-100) --80 + j*(30) -39 + j*(37) -77 + j*(-76) --37 + j*(-143) --120 + j*(-40) --34 + j*(30) -1 + j*(-59) --99 + j*(-75) --117 + j*(10) --101 + j*(12) --173 + j*(83) --59 + j*(276) -235 + j*(181) -185 + j*(-144) --124 + j*(-111) --71 + j*(191) -264 + j*(134) -277 + j*(-245) --90 + j*(-402) --404 + j*(-138) --311 + j*(268) -90 + j*(347) -272 + j*(21) -45 + j*(-173) --86 + j*(-25) -25 + j*(-8) --83 + j*(-120) --233 + j*(86) -33 + j*(272) -226 + j*(-22) --98 + j*(-202) --271 + j*(151) -78 + j*(340) -279 + j*(57) -95 + j*(-117) --16 + j*(-28) --4 + j*(8) --40 + j*(69) -78 + j*(198) -313 + j*(81) -272 + j*(-214) -9 + j*(-281) --112 + j*(-127) --78 + j*(-23) --30 + j*(23) -56 + j*(36) -119 + j*(-63) -35 + j*(-156) --47 + j*(-92) -40 + j*(-49) -76 + j*(-214) --148 + j*(-326) --365 + j*(-142) --317 + j*(88) --206 + j*(148) --161 + j*(208) --7 + j*(267) -136 + j*(120) -17 + j*(-25) --86 + j*(106) -84 + j*(185) -154 + j*(1) --25 + j*(-38) --8 + j*(156) -233 + j*(115) -233 + j*(-157) -8 + j*(-231) --100 + j*(-129) --130 + j*(-64) --159 + j*(37) --62 + j*(146) -66 + j*(83) -18 + j*(-22) --67 + j*(44) -8 + j*(146) -142 + j*(98) -158 + j*(-36) -64 + j*(-110) --27 + j*(-71) --23 + j*(11) -54 + j*(26) -107 + j*(-57) -52 + j*(-185) --147 + j*(-221) --330 + j*(-16) --221 + j*(300) -131 + j*(345) -312 + j*(74) -192 + j*(-150) -23 + j*(-168) --71 + j*(-105) --102 + j*(1) --19 + j*(91) -97 + j*(45) -91 + j*(-66) -22 + j*(-88) -5 + j*(-83) --33 + j*(-119) --137 + j*(-95) --184 + j*(43) --74 + j*(170) -91 + j*(133) -119 + j*(-13) -25 + j*(-51) -32 + j*(11) -110 + j*(-62) -6 + j*(-186) --143 + j*(-97) --69 + j*(28) -4 + j*(-74) --153 + j*(-144) --278 + j*(28) --190 + j*(209) --28 + j*(267) -151 + j*(206) -205 + j*(-18) --10 + j*(-141) --157 + j*(59) -28 + j*(205) -158 + j*(63) -80 + j*(-13) -98 + j*(9) -91 + j*(-105) --86 + j*(-76) --18 + j*(132) -211 + j*(1) -16 + j*(-245) --234 + j*(1) -52 + j*(231) -251 + j*(-89) --86 + j*(-255) --217 + j*(79) -84 + j*(165) -110 + j*(-91) --110 + j*(-47) --6 + j*(163) -218 + j*(46) -154 + j*(-189) --40 + j*(-220) --156 + j*(-128) --184 + j*(17) --69 + j*(131) -78 + j*(55) -26 + j*(-98) --136 + j*(-69) --156 + j*(100) --10 + j*(195) -146 + j*(112) -135 + j*(-62) --30 + j*(-98) --86 + j*(69) -99 + j*(153) -250 + j*(-33) -122 + j*(-255) --124 + j*(-231) --188 + j*(-32) --55 + j*(51) --4 + j*(-64) --158 + j*(-104) --240 + j*(84) --83 + j*(220) -44 + j*(142) -14 + j*(95) -55 + j*(151) -163 + j*(98) -175 + j*(-11) -154 + j*(-71) -121 + j*(-178) --61 + j*(-245) --223 + j*(-83) --134 + j*(109) -23 + j*(90) -40 + j*(-26) --63 + j*(-75) --184 + j*(28) --112 + j*(262) -214 + j*(273) -328 + j*(-78) -25 + j*(-257) --150 + j*(-34) --2 + j*(88) -49 + j*(14) -53 + j*(50) -209 + j*(-34) -84 + j*(-334) --343 + j*(-233) --317 + j*(254) -139 + j*(308) -239 + j*(-45) -21 + j*(-132) -0 + j*(-38) -14 + j*(-110) --142 + j*(-103) --156 + j*(95) -34 + j*(137) -92 + j*(-17) --23 + j*(-77) --86 + j*(4) --31 + j*(71) -35 + j*(28) --18 + j*(-49) --136 + j*(23) --76 + j*(206) -143 + j*(209) -216 + j*(33) -142 + j*(-41) -165 + j*(-47) -182 + j*(-200) --25 + j*(-333) --278 + j*(-192) --284 + j*(89) --81 + j*(228) -116 + j*(163) -187 + j*(-5) -106 + j*(-158) --52 + j*(-189) --170 + j*(-98) --185 + j*(35) --110 + j*(132) --6 + j*(145) -54 + j*(98) -74 + j*(59) -112 + j*(23) -127 + j*(-89) --16 + j*(-196) --223 + j*(-80) --173 + j*(192) -114 + j*(220) -196 + j*(-34) --5 + j*(-118) --51 + j*(45) -115 + j*(42) -88 + j*(-138) --77 + j*(-112) --34 + j*(0) -28 + j*(-119) --189 + j*(-197) --359 + j*(57) --176 + j*(310) -58 + j*(261) -83 + j*(140) -59 + j*(148) -132 + j*(187) -263 + j*(144) -366 + j*(-21) -301 + j*(-267) -38 + j*(-374) --177 + j*(-218) --143 + j*(-13) -6 + j*(8) -45 + j*(-118) --83 + j*(-208) --263 + j*(-126) --303 + j*(107) --120 + j*(285) -124 + j*(221) -164 + j*(6) -16 + j*(-66) --30 + j*(45) -92 + j*(52) -81 + j*(-104) --105 + j*(-95) --105 + j*(107) -95 + j*(117) -110 + j*(-64) --30 + j*(-69) --7 + j*(24) -49 + j*(-38) --51 + j*(-72) --76 + j*(49) -45 + j*(69) -59 + j*(-28) -1 + j*(-32) -18 + j*(-15) -1 + j*(-49) --28 + j*(1) -68 + j*(8) -63 + j*(-148) --140 + j*(-156) --158 + j*(49) -18 + j*(35) --69 + j*(-136) --291 + j*(12) --151 + j*(303) -156 + j*(231) -154 + j*(-16) -4 + j*(-32) -25 + j*(35) -49 + j*(-44) --81 + j*(-60) --117 + j*(100) -45 + j*(158) -107 + j*(18) --14 + j*(-22) --25 + j*(106) -119 + j*(108) -124 + j*(-33) -1 + j*(-24) -39 + j*(105) -204 + j*(71) -243 + j*(-117) -103 + j*(-262) --107 + j*(-233) --186 + j*(-18) -9 + j*(117) -169 + j*(-78) --38 + j*(-264) --255 + j*(-65) --93 + j*(146) -71 + j*(24) --35 + j*(-64) --45 + j*(53) -103 + j*(7) -45 + j*(-185) --169 + j*(-179) --259 + j*(-13) --221 + j*(146) --75 + j*(259) -122 + j*(190) -117 + j*(1) --24 + j*(11) -30 + j*(129) -163 + j*(53) -115 + j*(-79) -39 + j*(-78) -24 + j*(-94) --67 + j*(-115) --146 + j*(-1) --71 + j*(117) -44 + j*(117) -119 + j*(50) -122 + j*(-75) --22 + j*(-142) --129 + j*(-4) --5 + j*(119) -114 + j*(24) -69 + j*(-62) -50 + j*(-61) -43 + j*(-132) --81 + j*(-155) --127 + j*(-49) --80 + j*(-35) --148 + j*(-53) --191 + j*(80) --61 + j*(153) --11 + j*(72) --51 + j*(94) -46 + j*(123) -75 + j*(-23) --107 + j*(-56) --169 + j*(133) --46 + j*(234) -39 + j*(260) -209 + j*(301) -429 + j*(98) -305 + j*(-234) --11 + j*(-199) --4 + j*(39) -181 + j*(17) -167 + j*(-130) -95 + j*(-141) -110 + j*(-161) -57 + j*(-264) --107 + j*(-279) --221 + j*(-151) --187 + j*(2) --64 + j*(31) --30 + j*(-67) --136 + j*(-105) --219 + j*(-16) --222 + j*(110) --134 + j*(257) -118 + j*(292) -275 + j*(26) -51 + j*(-173) --101 + j*(43) -176 + j*(127) -243 + j*(-247) --187 + j*(-356) --349 + j*(45) --35 + j*(218) -104 + j*(-2) --42 + j*(-104) --130 + j*(-30) --140 + j*(59) --53 + j*(153) -100 + j*(58) --21 + j*(-139) --265 + j*(11) --124 + j*(286) -123 + j*(177) -21 + j*(18) --54 + j*(158) -110 + j*(206) -146 + j*(98) -148 + j*(144) -346 + j*(78) -331 + j*(-241) -21 + j*(-313) --62 + j*(-134) --5 + j*(-163) --192 + j*(-202) --315 + j*(64) --100 + j*(282) -128 + j*(213) -204 + j*(84) -226 + j*(-52) -133 + j*(-189) --13 + j*(-185) --60 + j*(-127) --117 + j*(-110) --192 + j*(11) --81 + j*(163) -76 + j*(117) -71 + j*(33) -98 + j*(65) -218 + j*(-32) -136 + j*(-245) --103 + j*(-230) --140 + j*(-43) --17 + j*(-5) -2 + j*(-107) --103 + j*(-146) --204 + j*(-68) --201 + j*(74) --77 + j*(156) -43 + j*(87) -18 + j*(-26) --78 + j*(-23) --92 + j*(71) --6 + j*(110) -65 + j*(51) -54 + j*(-28) -3 + j*(-69) --63 + j*(-95) --188 + j*(-63) --260 + j*(119) --112 + j*(305) -105 + j*(266) -153 + j*(124) -122 + j*(88) -158 + j*(67) -161 + j*(-8) -119 + j*(-23) -158 + j*(-27) -180 + j*(-141) -59 + j*(-246) --91 + j*(-214) --161 + j*(-121) --182 + j*(-28) --158 + j*(57) --108 + j*(107) --62 + j*(150) -40 + j*(182) -164 + j*(95) -141 + j*(-78) --38 + j*(-122) --150 + j*(40) --28 + j*(221) -210 + j*(173) -235 + j*(-68) -36 + j*(-117) -44 + j*(62) -269 + j*(-25) -148 + j*(-341) --221 + j*(-246) --154 + j*(107) -140 + j*(24) -11 + j*(-214) --194 + j*(-41) --2 + j*(136) -152 + j*(-42) -34 + j*(-159) -0 + j*(-144) --70 + j*(-254) --342 + j*(-173) --310 + j*(194) -59 + j*(204) -55 + j*(-135) --282 + j*(-95) --249 + j*(260) -87 + j*(286) -177 + j*(19) -3 + j*(-105) --130 + j*(-4) --79 + j*(127) -51 + j*(107) -32 + j*(-21) --107 + j*(11) --69 + j*(170) -93 + j*(142) -66 + j*(13) --25 + j*(60) -45 + j*(134) -104 + j*(72) -62 + j*(64) -124 + j*(116) -233 + j*(27) -179 + j*(-120) -54 + j*(-121) -39 + j*(-40) -120 + j*(-28) -174 + j*(-146) -57 + j*(-303) --192 + j*(-267) --262 + j*(-21) --100 + j*(103) --4 + j*(28) --45 + j*(-1) --27 + j*(39) -15 + j*(4) --26 + j*(-27) --45 + j*(16) --8 + j*(23) --14 + j*(3) --22 + j*(30) -24 + j*(40) -49 + j*(-11) -18 + j*(-54) --32 + j*(-62) --83 + j*(-26) --80 + j*(49) --13 + j*(76) -18 + j*(38) -1 + j*(34) -29 + j*(61) -78 + j*(30) -78 + j*(-23) -62 + j*(-53) -33 + j*(-89) --33 + j*(-95) --72 + j*(-38) --35 + j*(1) --16 + j*(-37) --78 + j*(-54) --124 + j*(26) --56 + j*(110) -44 + j*(68) -13 + j*(-25) --82 + j*(21) --27 + j*(143) -125 + j*(108) -138 + j*(-32) -62 + j*(-75) -40 + j*(-86) --35 + j*(-128) --145 + j*(-28) --37 + j*(131) -164 + j*(13) -54 + j*(-241) --240 + j*(-185) --275 + j*(87) --105 + j*(175) --54 + j*(129) --41 + j*(175) -83 + j*(185) -124 + j*(48) -2 + j*(26) -26 + j*(180) -254 + j*(150) -280 + j*(-119) -47 + j*(-206) --38 + j*(-61) -35 + j*(-46) --37 + j*(-86) --65 + j*(52) -115 + j*(58) -78 + j*(-153) --162 + j*(-54) -6 + j*(223) -328 + j*(5) -98 + j*(-344) --228 + j*(-127) --13 + j*(134) -175 + j*(-97) --51 + j*(-226) --109 + j*(-45) -19 + j*(-105) --165 + j*(-229) --330 + j*(17) --105 + j*(196) -25 + j*(25) --117 + j*(-30) --136 + j*(91) --75 + j*(111) --64 + j*(157) -81 + j*(193) -156 + j*(-6) --69 + j*(-76) --107 + j*(180) -178 + j*(200) -199 + j*(-71) --4 + j*(-74) -49 + j*(42) -105 + j*(-75) --48 + j*(-87) --8 + j*(64) -129 + j*(-42) --34 + j*(-173) --140 + j*(16) -51 + j*(69) -30 + j*(-128) --188 + j*(-42) --73 + j*(185) -127 + j*(80) -44 + j*(-42) -45 + j*(36) -153 + j*(-95) --71 + j*(-272) --311 + j*(-13) --74 + j*(242) -141 + j*(32) --62 + j*(-125) --179 + j*(77) --16 + j*(167) -16 + j*(71) --38 + j*(141) -119 + j*(219) -250 + j*(59) -155 + j*(-83) -79 + j*(-50) -105 + j*(-57) -56 + j*(-115) --28 + j*(-63) -15 + j*(38) -155 + j*(28) -233 + j*(-149) -82 + j*(-362) --228 + j*(-315) --295 + j*(-9) --49 + j*(83) --19 + j*(-139) --301 + j*(-110) --281 + j*(252) -97 + j*(297) -186 + j*(-23) --48 + j*(-92) --55 + j*(87) -105 + j*(33) -14 + j*(-136) --166 + j*(-42) --105 + j*(145) -69 + j*(142) -126 + j*(14) -69 + j*(-76) --10 + j*(-82) --33 + j*(-52) --43 + j*(-77) --158 + j*(-76) --227 + j*(112) --27 + j*(276) -199 + j*(119) -109 + j*(-119) --103 + j*(-88) --129 + j*(78) --34 + j*(158) -71 + j*(153) -141 + j*(63) -81 + j*(-21) -36 + j*(50) -183 + j*(53) -187 + j*(-201) --153 + j*(-245) --253 + j*(144) -149 + j*(292) -339 + j*(-86) -25 + j*(-294) --154 + j*(-68) --1 + j*(33) -15 + j*(-88) --103 + j*(-47) --32 + j*(57) -37 + j*(-40) --107 + j*(-82) --166 + j*(107) -23 + j*(222) -186 + j*(107) -190 + j*(-50) -103 + j*(-158) --57 + j*(-165) --136 + j*(8) -44 + j*(134) -214 + j*(-54) -40 + j*(-269) --199 + j*(-137) --110 + j*(89) -91 + j*(24) -50 + j*(-169) --138 + j*(-184) --230 + j*(-40) --163 + j*(98) --31 + j*(94) --35 + j*(-19) --166 + j*(23) --93 + j*(205) -140 + j*(119) -37 + j*(-144) --257 + j*(-19) --130 + j*(305) -187 + j*(207) -112 + j*(-46) --50 + j*(41) -73 + j*(127) -92 + j*(-15) --51 + j*(43) -88 + j*(204) -276 + j*(23) -107 + j*(-150) -25 + j*(11) -241 + j*(-28) -145 + j*(-346) --242 + j*(-277) --223 + j*(87) -62 + j*(66) --9 + j*(-175) --272 + j*(-85) --260 + j*(204) --30 + j*(338) -209 + j*(269) -321 + j*(43) -205 + j*(-158) -29 + j*(-143) -21 + j*(-46) -69 + j*(-63) -43 + j*(-95) -40 + j*(-97) -26 + j*(-156) --83 + j*(-180) --163 + j*(-90) --137 + j*(-2) --98 + j*(28) --65 + j*(42) --40 + j*(33) --45 + j*(40) -2 + j*(71) -71 + j*(3) -12 + j*(-86) --49 + j*(-52) --18 + j*(-75) --158 + j*(-172) --394 + j*(39) --216 + j*(417) -215 + j*(356) -267 + j*(-4) -39 + j*(-91) --21 + j*(19) -14 + j*(40) -23 + j*(61) -95 + j*(56) -98 + j*(-49) -4 + j*(-43) -59 + j*(7) -77 + j*(-148) --192 + j*(-173) --273 + j*(172) -69 + j*(319) -239 + j*(54) -88 + j*(-60) -86 + j*(-1) -102 + j*(-127) --129 + j*(-129) --141 + j*(173) -198 + j*(213) -281 + j*(-101) -58 + j*(-202) -4 + j*(-91) -53 + j*(-126) --39 + j*(-185) --129 + j*(-119) --148 + j*(-39) --126 + j*(63) -30 + j*(96) -95 + j*(-108) --163 + j*(-204) --314 + j*(91) --50 + j*(296) -163 + j*(134) -129 + j*(0) -139 + j*(-59) -47 + j*(-234) --250 + j*(-158) --202 + j*(202) -178 + j*(155) -110 + j*(-235) --288 + j*(-155) --218 + j*(224) -96 + j*(153) --20 + j*(-86) --237 + j*(98) --28 + j*(359) -277 + j*(214) -241 + j*(-70) -39 + j*(-107) --6 + j*(23) -114 + j*(50) -146 + j*(-100) --25 + j*(-165) --116 + j*(1) -40 + j*(86) -90 + j*(-74) --91 + j*(-78) --48 + j*(143) -234 + j*(71) -175 + j*(-279) --200 + j*(-285) --286 + j*(40) --75 + j*(151) --17 + j*(57) --71 + j*(105) -59 + j*(202) -235 + j*(68) -175 + j*(-158) --39 + j*(-190) --136 + j*(-37) --61 + j*(75) -27 + j*(76) -87 + j*(53) -165 + j*(-28) -125 + j*(-212) --119 + j*(-264) --262 + j*(-40) --106 + j*(139) -42 + j*(45) --30 + j*(-46) --74 + j*(23) --8 + j*(40) --19 + j*(-18) --76 + j*(11) --53 + j*(69) --13 + j*(94) -71 + j*(114) -192 + j*(-9) -81 + j*(-239) --222 + j*(-189) --243 + j*(119) -6 + j*(170) -20 + j*(-16) --153 + j*(39) --67 + j*(248) -168 + j*(204) -190 + j*(6) -79 + j*(-42) -55 + j*(11) -116 + j*(11) -151 + j*(-91) -37 + j*(-217) --189 + j*(-141) --180 + j*(150) -139 + j*(216) -272 + j*(-98) -0 + j*(-273) --162 + j*(-72) --13 + j*(18) --18 + j*(-144) --253 + j*(-80) --201 + j*(224) -119 + j*(223) -158 + j*(-62) --76 + j*(-111) --123 + j*(72) --8 + j*(115) -5 + j*(85) -42 + j*(146) -187 + j*(103) -190 + j*(-75) -51 + j*(-117) -18 + j*(-45) -43 + j*(-53) -4 + j*(-48) -48 + j*(8) -132 + j*(-81) -28 + j*(-197) --75 + j*(-110) -22 + j*(-79) --21 + j*(-257) --312 + j*(-221) --363 + j*(127) --65 + j*(267) -102 + j*(74) -8 + j*(-53) --57 + j*(-21) --49 + j*(-23) --98 + j*(-45) --168 + j*(1) --192 + j*(103) --134 + j*(218) -10 + j*(260) -124 + j*(185) -151 + j*(85) -132 + j*(1) -42 + j*(-52) --50 + j*(34) -49 + j*(156) -209 + j*(53) -132 + j*(-117) -2 + j*(-72) -53 + j*(-21) -35 + j*(-124) --127 + j*(-79) --94 + j*(112) -71 + j*(101) -65 + j*(6) -58 + j*(45) -162 + j*(-21) -55 + j*(-196) --175 + j*(-70) --47 + j*(199) -252 + j*(92) -190 + j*(-209) --69 + j*(-199) --71 + j*(-8) -73 + j*(-34) -11 + j*(-181) --168 + j*(-110) --112 + j*(105) -133 + j*(71) -139 + j*(-204) --138 + j*(-275) --276 + j*(-60) --179 + j*(93) --94 + j*(119) -18 + j*(148) -162 + j*(6) -26 + j*(-228) --247 + j*(-132) --196 + j*(110) --56 + j*(52) --201 + j*(25) --186 + j*(303) -185 + j*(322) -255 + j*(-55) --76 + j*(-139) --141 + j*(135) -88 + j*(190) -140 + j*(19) -35 + j*(-28) --6 + j*(30) -34 + j*(95) -163 + j*(86) -219 + j*(-117) --15 + j*(-264) --230 + j*(-56) --86 + j*(169) -83 + j*(84) -21 + j*(7) -28 + j*(96) -162 + j*(54) -146 + j*(-94) -45 + j*(-119) -13 + j*(-106) --49 + j*(-112) --103 + j*(-21) --24 + j*(58) -58 + j*(6) -44 + j*(-64) --5 + j*(-103) --108 + j*(-93) --155 + j*(63) -35 + j*(171) -190 + j*(-23) -7 + j*(-206) --175 + j*(-45) --35 + j*(121) -113 + j*(-3) -18 + j*(-146) --119 + j*(-103) --148 + j*(11) --88 + j*(97) -18 + j*(88) -26 + j*(-2) --47 + j*(23) -50 + j*(112) -197 + j*(-47) -23 + j*(-272) --256 + j*(-141) --197 + j*(119) --28 + j*(103) --75 + j*(49) --61 + j*(182) -146 + j*(168) -223 + j*(-352) --117 + j*(-362) --214 + j*(-116) --118 + j*(-18) --79 + j*(3) -4 + j*(16) -34 + j*(-110) --133 + j*(-130) --123 + j*(67) -101 + j*(-2) --35 + j*(-277) --377 + j*(-114) --243 + j*(260) -86 + j*(173) -13 + j*(-74) --164 + j*(1) --120 + j*(128) --76 + j*(166) -41 + j*(252) -271 + j*(109) -152 + j*(-218) --205 + j*(-132) --139 + j*(202) -138 + j*(141) -63 + j*(-48) --29 + j*(73) -163 + j*(103) -194 + j*(-156) --71 + j*(-252) --256 + j*(-65) --218 + j*(179) -21 + j*(313) -284 + j*(127) -158 + j*(-184) --140 + j*(-66) -32 + j*(200) -288 + j*(-52) --25 + j*(-322) --303 + j*(11) -8 + j*(266) -199 + j*(1) --21 + j*(-95) --13 + j*(100) -170 + j*(16) -52 + j*(-146) --64 + j*(-15) -80 + j*(44) -100 + j*(-100) --12 + j*(-95) -40 + j*(-29) -87 + j*(-139) --32 + j*(-217) --127 + j*(-185) --219 + j*(-163) --351 + j*(-13) --260 + j*(244) -8 + j*(251) -52 + j*(61) --82 + j*(55) --55 + j*(198) -103 + j*(207) -172 + j*(102) -163 + j*(34) -175 + j*(-6) -187 + j*(-92) -112 + j*(-191) --13 + j*(-187) --48 + j*(-117) --37 + j*(-129) --129 + j*(-146) --194 + j*(-21) --95 + j*(64) --56 + j*(-2) --133 + j*(26) --59 + j*(139) -74 + j*(41) --53 + j*(-100) --219 + j*(56) --78 + j*(266) -144 + j*(188) -136 + j*(12) -25 + j*(2) -35 + j*(95) -173 + j*(95) -249 + j*(-93) -69 + j*(-274) --174 + j*(-158) --117 + j*(83) -91 + j*(48) -60 + j*(-139) --109 + j*(-133) --146 + j*(-28) --153 + j*(18) --174 + j*(133) --21 + j*(262) -191 + j*(147) -131 + j*(-84) --91 + j*(-60) --91 + j*(168) -141 + j*(219) -254 + j*(37) -179 + j*(-83) -151 + j*(-97) -132 + j*(-204) --59 + j*(-262) --197 + j*(-70) --52 + j*(82) -57 + j*(-21) --24 + j*(-64) -4 + j*(2) -58 + j*(-95) --100 + j*(-137) --112 + j*(71) -148 + j*(45) -110 + j*(-274) --224 + j*(-282) --287 + j*(-44) --231 + j*(-8) --341 + j*(89) --217 + j*(372) -134 + j*(326) -149 + j*(50) -1 + j*(65) -110 + j*(130) -159 + j*(-41) --1 + j*(-98) --35 + j*(-6) --40 + j*(-34) --161 + j*(46) --49 + j*(272) -239 + j*(190) -215 + j*(-86) -18 + j*(-94) -22 + j*(13) -71 + j*(-9) -58 + j*(-19) -90 + j*(-33) -60 + j*(-100) --13 + j*(-57) -71 + j*(-2) -117 + j*(-132) --30 + j*(-194) --86 + j*(-75) --5 + j*(-81) --77 + j*(-177) --211 + j*(-114) --216 + j*(12) --179 + j*(95) --92 + j*(181) -43 + j*(148) -42 + j*(47) -11 + j*(85) -128 + j*(83) -135 + j*(-89) --26 + j*(-108) --13 + j*(-4) -34 + j*(-100) --165 + j*(-124) --202 + j*(153) -97 + j*(221) -173 + j*(-41) --33 + j*(-90) --23 + j*(67) -114 + j*(-3) -16 + j*(-141) --141 + j*(-59) --120 + j*(104) -6 + j*(171) -139 + j*(124) -180 + j*(-7) -117 + j*(-78) -108 + j*(-89) -84 + j*(-193) --108 + j*(-221) --190 + j*(-8) -10 + j*(79) -62 + j*(-123) --175 + j*(-160) --235 + j*(95) --3 + j*(199) -134 + j*(30) -48 + j*(-132) --129 + j*(-153) --287 + j*(-12) --277 + j*(249) --39 + j*(432) -274 + j*(365) -433 + j*(85) -322 + j*(-204) -59 + j*(-260) --57 + j*(-103) -18 + j*(-27) -33 + j*(-77) --15 + j*(-50) -49 + j*(-8) -103 + j*(-109) -4 + j*(-202) --118 + j*(-167) --178 + j*(-77) --171 + j*(42) --45 + j*(113) -62 + j*(-1) --47 + j*(-123) --185 + j*(-22) --116 + j*(124) -4 + j*(99) -1 + j*(15) --64 + j*(18) --69 + j*(95) -28 + j*(132) -93 + j*(33) --4 + j*(-34) --49 + j*(76) -84 + j*(90) -58 + j*(-60) --105 + j*(33) -72 + j*(223) -306 + j*(-32) -3 + j*(-308) --298 + j*(17) -28 + j*(320) -315 + j*(13) -51 + j*(-237) --146 + j*(-25) --1 + j*(113) -62 + j*(49) -73 + j*(97) -251 + j*(71) -310 + j*(-189) -95 + j*(-368) --134 + j*(-315) --258 + j*(-168) --263 + j*(39) --74 + j*(165) -98 + j*(18) --33 + j*(-171) --260 + j*(-57) --216 + j*(215) -39 + j*(288) -199 + j*(135) -175 + j*(-11) -128 + j*(-47) -139 + j*(-87) -107 + j*(-184) --12 + j*(-233) --125 + j*(-194) --191 + j*(-104) --168 + j*(8) --58 + j*(2) --112 + j*(-141) --364 + j*(-62) --354 + j*(296) --7 + j*(395) -122 + j*(168) -4 + j*(133) -89 + j*(241) -245 + j*(127) -202 + j*(-16) -177 + j*(-44) -158 + j*(-179) --78 + j*(-233) --194 + j*(-3) --25 + j*(98) --21 + j*(-19) --141 + j*(86) -23 + j*(247) -190 + j*(107) -105 + j*(16) -142 + j*(83) -241 + j*(-56) -65 + j*(-168) -5 + j*(20) -246 + j*(1) -198 + j*(-315) --134 + j*(-306) --176 + j*(-57) --74 + j*(-21) --92 + j*(25) -76 + j*(118) -253 + j*(-148) --59 + j*(-423) --412 + j*(-146) --233 + j*(209) -33 + j*(124) --13 + j*(-18) --54 + j*(36) -2 + j*(25) --38 + j*(-10) --30 + j*(65) -95 + j*(10) -16 + j*(-184) --251 + j*(-123) --256 + j*(179) -20 + j*(262) -134 + j*(60) -3 + j*(-25) --24 + j*(76) -87 + j*(51) -25 + j*(-78) --124 + j*(8) --28 + j*(175) -152 + j*(83) -81 + j*(-86) --64 + j*(-41) --49 + j*(65) --4 + j*(88) -44 + j*(122) -156 + j*(86) -158 + j*(-56) -40 + j*(-72) -57 + j*(4) -123 + j*(-68) -23 + j*(-143) --40 + j*(-57) -34 + j*(-45) --11 + j*(-144) --154 + j*(-81) --125 + j*(83) -10 + j*(102) -62 + j*(28) -48 + j*(-32) --8 + j*(-69) --83 + j*(-17) --49 + j*(91) -76 + j*(95) -133 + j*(-16) -76 + j*(-117) --46 + j*(-124) --100 + j*(-6) -15 + j*(78) -121 + j*(-42) -18 + j*(-172) --105 + j*(-120) --112 + j*(-68) --171 + j*(-49) --202 + j*(98) --40 + j*(182) -48 + j*(47) --74 + j*(1) --91 + j*(130) -13 + j*(153) -28 + j*(134) -112 + j*(191) -283 + j*(66) -190 + j*(-181) --50 + j*(-140) --25 + j*(47) -116 + j*(8) -77 + j*(-105) --1 + j*(-88) --8 + j*(-64) --26 + j*(-51) --6 + j*(-22) -13 + j*(-75) --98 + j*(-91) --134 + j*(87) -96 + j*(171) -262 + j*(-78) -49 + j*(-341) --283 + j*(-235) --309 + j*(95) --49 + j*(218) -96 + j*(40) --30 + j*(-72) --94 + j*(37) -9 + j*(51) --33 + j*(-47) --124 + j*(53) -39 + j*(127) -79 + j*(-116) --263 + j*(-139) --325 + j*(289) -103 + j*(416) -244 + j*(88) -29 + j*(35) -117 + j*(213) -332 + j*(40) -176 + j*(-206) --27 + j*(-109) -34 + j*(4) -69 + j*(-52) -26 + j*(-38) -86 + j*(-21) -98 + j*(-133) --35 + j*(-187) --146 + j*(-99) --163 + j*(30) --75 + j*(153) -102 + j*(144) -151 + j*(-22) -29 + j*(-74) -21 + j*(30) -142 + j*(8) -147 + j*(-128) -60 + j*(-193) --25 + j*(-213) --138 + j*(-165) --137 + j*(-36) --25 + j*(-57) --117 + j*(-185) --313 + j*(-41) --186 + j*(215) -73 + j*(129) -10 + j*(-91) --188 + j*(-33) --156 + j*(150) --1 + j*(170) -66 + j*(65) -9 + j*(-28) --105 + j*(-4) --117 + j*(129) -7 + j*(177) -62 + j*(92) -2 + j*(70) --1 + j*(146) -91 + j*(202) -249 + j*(173) -368 + j*(-40) -200 + j*(-308) --124 + j*(-233) --95 + j*(58) -148 + j*(-4) -25 + j*(-247) --243 + j*(-95) --110 + j*(173) -111 + j*(69) -13 + j*(-80) --71 + j*(30) -45 + j*(75) -62 + j*(-25) --4 + j*(-7) -66 + j*(32) -112 + j*(-86) --21 + j*(-180) --173 + j*(-95) --192 + j*(79) --62 + j*(213) -132 + j*(177) -175 + j*(3) -57 + j*(-47) -61 + j*(55) -217 + j*(21) -240 + j*(-191) -69 + j*(-334) --145 + j*(-303) --267 + j*(-139) --214 + j*(37) --87 + j*(57) --81 + j*(0) --100 + j*(49) --11 + j*(47) --57 + j*(-75) --234 + j*(18) --134 + j*(261) -125 + j*(190) -74 + j*(-13) --49 + j*(70) -92 + j*(134) -115 + j*(-39) --58 + j*(3) -84 + j*(188) -326 + j*(-57) -28 + j*(-380) --365 + j*(-95) --148 + j*(321) -235 + j*(210) -224 + j*(-69) -118 + j*(-110) -112 + j*(-178) --54 + j*(-281) --257 + j*(-122) --157 + j*(101) -25 + j*(32) --56 + j*(-122) --231 + j*(-43) --213 + j*(147) --79 + j*(205) --19 + j*(182) -27 + j*(203) -136 + j*(184) -176 + j*(63) -98 + j*(25) -138 + j*(98) -284 + j*(-20) -152 + j*(-266) --157 + j*(-163) --75 + j*(167) -272 + j*(98) -243 + j*(-262) --79 + j*(-310) --180 + j*(-104) --121 + j*(-22) --129 + j*(17) --73 + j*(122) -73 + j*(115) -127 + j*(-4) -89 + j*(-89) -13 + j*(-136) --88 + j*(-99) --75 + j*(14) -24 + j*(-11) --43 + j*(-105) --148 + j*(16) -12 + j*(148) -184 + j*(-37) -13 + j*(-256) --235 + j*(-158) --253 + j*(63) --132 + j*(175) -7 + j*(188) -121 + j*(86) -82 + j*(-61) --48 + j*(-65) --71 + j*(22) --37 + j*(45) --30 + j*(61) -25 + j*(79) -67 + j*(5) --13 + j*(-47) --65 + j*(34) -18 + j*(83) -67 + j*(-1) --18 + j*(-66) --122 + j*(-3) --121 + j*(146) -42 + j*(250) -243 + j*(139) -220 + j*(-100) -18 + j*(-141) --32 + j*(-6) -63 + j*(11) -41 + j*(-72) --39 + j*(-31) -7 + j*(40) -64 + j*(-4) -33 + j*(-47) -13 + j*(-38) --11 + j*(-57) --86 + j*(-13) --52 + j*(140) -160 + j*(158) -261 + j*(-52) -122 + j*(-205) -4 + j*(-161) -17 + j*(-146) --57 + j*(-216) --218 + j*(-132) --185 + j*(71) -6 + j*(81) -26 + j*(-89) --151 + j*(-119) --225 + j*(56) --95 + j*(184) -45 + j*(132) -45 + j*(26) --18 + j*(23) -0 + j*(76) -54 + j*(44) -15 + j*(1) --4 + j*(78) -135 + j*(101) -208 + j*(-83) -43 + j*(-216) --100 + j*(-126) --80 + j*(-51) --107 + j*(-56) --152 + j*(42) --45 + j*(132) -49 + j*(54) -0 + j*(1) -0 + j*(45) -58 + j*(7) -15 + j*(-72) --64 + j*(-62) --104 + j*(-23) --142 + j*(49) --80 + j*(156) -31 + j*(118) --28 + j*(48) --75 + j*(192) -141 + j*(274) -272 + j*(69) -136 + j*(-35) -148 + j*(63) -301 + j*(-52) -177 + j*(-295) --89 + j*(-259) --163 + j*(-65) --95 + j*(74) -64 + j*(137) -232 + j*(-18) -102 + j*(-238) --108 + j*(-122) -47 + j*(31) -162 + j*(-208) --146 + j*(-344) --315 + j*(-50) --107 + j*(96) --50 + j*(-24) --119 + j*(23) --1 + j*(54) --10 + j*(-113) --206 + j*(-80) --172 + j*(90) --112 + j*(31) --278 + j*(105) --152 + j*(428) -272 + j*(356) -274 + j*(-40) --8 + j*(-49) -43 + j*(140) -188 + j*(39) -100 + j*(-66) -71 + j*(-19) -104 + j*(-89) --40 + j*(-136) --99 + j*(35) -70 + j*(86) -100 + j*(-71) --41 + j*(-81) --35 + j*(41) -64 + j*(29) -54 + j*(-48) -4 + j*(-39) -16 + j*(-15) -30 + j*(-28) -23 + j*(-38) -37 + j*(-33) -69 + j*(-82) -5 + j*(-177) --146 + j*(-139) --141 + j*(26) -6 + j*(3) --82 + j*(-157) --302 + j*(-16) --176 + j*(260) -77 + j*(187) -21 + j*(42) -0 + j*(155) -213 + j*(106) -161 + j*(-171) --105 + j*(-142) --74 + j*(41) --6 + j*(-48) --200 + j*(-20) --127 + j*(281) -233 + j*(215) -174 + j*(-139) --139 + j*(-53) --16 + j*(238) -275 + j*(110) -204 + j*(-158) -18 + j*(-156) --12 + j*(-95) --54 + j*(-97) --115 + j*(-15) --56 + j*(88) -47 + j*(91) -103 + j*(29) -100 + j*(-44) -52 + j*(-76) -48 + j*(-64) -62 + j*(-144) --107 + j*(-223) --295 + j*(-20) --124 + j*(269) -211 + j*(180) -210 + j*(-136) --30 + j*(-187) --75 + j*(-37) -23 + j*(-43) --26 + j*(-152) --160 + j*(-112) --173 + j*(-1) --141 + j*(27) --179 + j*(72) --134 + j*(211) -62 + j*(235) -153 + j*(57) -18 + j*(-49) --91 + j*(59) --9 + j*(190) -154 + j*(190) -287 + j*(50) -264 + j*(-194) --6 + j*(-338) --285 + j*(-137) --204 + j*(201) -122 + j*(242) -264 + j*(-21) -90 + j*(-225) --133 + j*(-137) --104 + j*(73) -94 + j*(60) -81 + j*(-141) --124 + j*(-130) --107 + j*(52) -30 + j*(-14) --123 + j*(-132) --267 + j*(105) --4 + j*(286) -173 + j*(42) --68 + j*(-75) --126 + j*(203) -191 + j*(258) -284 + j*(-37) -79 + j*(-140) -24 + j*(-43) -53 + j*(-62) --16 + j*(-51) -40 + j*(43) -168 + j*(-70) -23 + j*(-254) --206 + j*(-125) --115 + j*(107) -86 + j*(30) --8 + j*(-153) --216 + j*(-48) --146 + j*(204) -122 + j*(213) -206 + j*(-9) -70 + j*(-124) --12 + j*(-57) -35 + j*(-30) -35 + j*(-92) --35 + j*(-102) --54 + j*(-55) --30 + j*(-59) --64 + j*(-103) --161 + j*(-87) --221 + j*(37) --135 + j*(186) -44 + j*(175) -94 + j*(25) -1 + j*(-35) --40 + j*(4) --54 + j*(4) --107 + j*(71) -4 + j*(193) -194 + j*(51) -24 + j*(-204) --309 + j*(-17) --148 + j*(399) -307 + j*(319) -320 + j*(-84) -30 + j*(-134) -13 + j*(58) -161 + j*(40) -166 + j*(-69) -151 + j*(-122) -107 + j*(-256) --153 + j*(-310) --333 + j*(-22) --107 + j*(238) -148 + j*(95) -56 + j*(-95) --53 + j*(-16) -44 + j*(20) -18 + j*(-106) --148 + j*(-36) --59 + j*(171) -180 + j*(93) -134 + j*(-147) --69 + j*(-138) --74 + j*(8) -19 + j*(6) -6 + j*(-56) --35 + j*(-47) --35 + j*(-32) --45 + j*(-34) --56 + j*(-30) --88 + j*(-30) --137 + j*(29) --98 + j*(129) -4 + j*(142) -40 + j*(108) -86 + j*(119) -192 + j*(45) -163 + j*(-137) --23 + j*(-178) --109 + j*(-47) --45 + j*(38) -23 + j*(16) -29 + j*(-38) --18 + j*(-78) --82 + j*(-54) --97 + j*(-8) --124 + j*(24) --136 + j*(148) -54 + j*(250) -238 + j*(50) -54 + j*(-159) --132 + j*(24) -81 + j*(172) -197 + j*(-84) --91 + j*(-178) --169 + j*(130) -138 + j*(212) -238 + j*(-50) -71 + j*(-148) -27 + j*(-93) -21 + j*(-141) --101 + j*(-151) --175 + j*(-35) --143 + j*(88) --20 + j*(175) -168 + j*(91) -126 + j*(-157) --150 + j*(-144) --145 + j*(139) -122 + j*(133) -107 + j*(-90) --35 + j*(-45) -81 + j*(3) -63 + j*(-230) --289 + j*(-218) --350 + j*(189) -14 + j*(330) -170 + j*(72) --1 + j*(-24) --21 + j*(124) -160 + j*(117) -177 + j*(-96) --41 + j*(-163) --151 + j*(40) -27 + j*(177) -166 + j*(32) -45 + j*(-67) -13 + j*(75) -225 + j*(71) -252 + j*(-197) -13 + j*(-288) --76 + j*(-163) --52 + j*(-177) --203 + j*(-203) --318 + j*(5) --170 + j*(200) -23 + j*(168) -77 + j*(37) -5 + j*(-57) --119 + j*(-8) --84 + j*(159) -120 + j*(156) -163 + j*(-39) -38 + j*(-105) -2 + j*(-85) --69 + j*(-130) --208 + j*(-8) --69 + j*(190) -144 + j*(28) --67 + j*(-190) --315 + j*(65) --78 + j*(351) -194 + j*(199) -129 + j*(35) -116 + j*(79) -212 + j*(-13) -105 + j*(-165) --42 + j*(-103) --18 + j*(-26) --33 + j*(-53) --98 + j*(36) -28 + j*(151) -187 + j*(27) -95 + j*(-152) --76 + j*(-102) --53 + j*(45) -81 + j*(30) -79 + j*(-110) --73 + j*(-139) --142 + j*(-1) --56 + j*(91) -11 + j*(70) -44 + j*(74) -137 + j*(27) -115 + j*(-141) --91 + j*(-153) --125 + j*(53) -66 + j*(93) -107 + j*(-72) --11 + j*(-115) --41 + j*(-74) --77 + j*(-88) --153 + j*(-8) --74 + j*(104) -13 + j*(44) --59 + j*(32) -12 + j*(166) -238 + j*(53) -144 + j*(-252) --177 + j*(-214) --190 + j*(52) --13 + j*(71) --35 + j*(-33) --102 + j*(30) --28 + j*(89) -14 + j*(33) --23 + j*(18) --9 + j*(43) -12 + j*(16) --22 + j*(-2) --42 + j*(20) --49 + j*(36) --61 + j*(78) --13 + j*(137) -71 + j*(127) -106 + j*(69) -105 + j*(23) -86 + j*(-14) -47 + j*(-19) -42 + j*(12) -81 + j*(4) -81 + j*(-41) -54 + j*(-64) -29 + j*(-87) --44 + j*(-96) --117 + j*(-6) --57 + j*(128) -97 + j*(144) -198 + j*(35) -192 + j*(-114) -61 + j*(-221) --120 + j*(-144) --91 + j*(68) -144 + j*(69) -187 + j*(-185) --45 + j*(-290) --186 + j*(-134) --126 + j*(-23) --78 + j*(-33) --77 + j*(-47) --109 + j*(-83) --236 + j*(-37) --226 + j*(202) -79 + j*(271) -223 + j*(-45) --52 + j*(-234) --246 + j*(-39) --148 + j*(95) --148 + j*(66) --197 + j*(212) -18 + j*(345) -206 + j*(161) -88 + j*(6) -4 + j*(106) -112 + j*(158) -176 + j*(88) -209 + j*(41) -247 + j*(-77) -134 + j*(-211) --4 + j*(-175) --25 + j*(-144) --153 + j*(-154) --265 + j*(98) -23 + j*(327) -317 + j*(71) -131 + j*(-193) --20 + j*(-42) -173 + j*(-32) -96 + j*(-317) --264 + j*(-239) --225 + j*(116) -62 + j*(96) -35 + j*(-115) --110 + j*(-95) --129 + j*(-40) --211 + j*(5) --209 + j*(233) -86 + j*(327) -258 + j*(68) -91 + j*(-89) -32 + j*(23) -170 + j*(-24) -79 + j*(-250) --222 + j*(-204) --284 + j*(109) --35 + j*(264) -156 + j*(127) -106 + j*(-33) -9 + j*(1) -76 + j*(74) -187 + j*(-17) -138 + j*(-182) --18 + j*(-234) --148 + j*(-174) --220 + j*(-49) --185 + j*(90) --85 + j*(149) --6 + j*(161) -112 + j*(158) -230 + j*(0) -107 + j*(-209) --117 + j*(-146) --82 + j*(18) --1 + j*(-53) --151 + j*(-81) --170 + j*(132) -49 + j*(147) -28 + j*(-42) --135 + j*(54) -24 + j*(213) -176 + j*(22) --32 + j*(-86) --86 + j*(156) -201 + j*(181) -238 + j*(-119) --22 + j*(-173) --73 + j*(19) -60 + j*(59) -112 + j*(-21) -105 + j*(-103) -6 + j*(-199) --177 + j*(-119) --129 + j*(101) -83 + j*(54) --2 + j*(-140) --205 + j*(7) --2 + j*(243) -291 + j*(10) -77 + j*(-358) --356 + j*(-235) --397 + j*(187) --103 + j*(388) -156 + j*(310) -265 + j*(131) -234 + j*(-39) -114 + j*(-98) -68 + j*(-42) -121 + j*(-46) -118 + j*(-134) -43 + j*(-175) --6 + j*(-183) --94 + j*(-211) --239 + j*(-127) --238 + j*(78) --62 + j*(156) -25 + j*(55) --22 + j*(17) --8 + j*(59) -60 + j*(25) -52 + j*(-66) --31 + j*(-122) --165 + j*(-97) --246 + j*(84) --81 + j*(274) -169 + j*(173) -129 + j*(-61) --41 + j*(-42) --1 + j*(53) -28 + j*(-37) --127 + j*(-18) --95 + j*(196) -140 + j*(185) -142 + j*(-6) -23 + j*(27) -132 + j*(103) -218 + j*(-57) -79 + j*(-162) -8 + j*(-87) -34 + j*(-99) --49 + j*(-119) --70 + j*(-13) -31 + j*(-25) --42 + j*(-132) --174 + j*(-13) --49 + j*(132) -66 + j*(23) --40 + j*(-21) --6 + j*(108) -163 + j*(21) -55 + j*(-175) --128 + j*(-65) --13 + j*(71) -65 + j*(-69) --99 + j*(-96) --74 + j*(76) -100 + j*(-28) --100 + j*(-233) --386 + j*(34) --129 + j*(409) -279 + j*(222) -163 + j*(-144) --134 + j*(-53) --40 + j*(199) -188 + j*(122) -153 + j*(-63) -43 + j*(-46) -86 + j*(-2) -121 + j*(-87) -28 + j*(-152) --52 + j*(-89) --8 + j*(-25) -50 + j*(-85) --23 + j*(-180) --165 + j*(-146) --204 + j*(-16) --154 + j*(54) --144 + j*(88) --98 + j*(173) -43 + j*(182) -98 + j*(55) -8 + j*(6) --11 + j*(95) -104 + j*(115) -175 + j*(6) -135 + j*(-130) --28 + j*(-204) --218 + j*(-63) --127 + j*(205) -177 + j*(165) -170 + j*(-130) --81 + j*(-122) --25 + j*(62) -99 + j*(-93) --175 + j*(-198) --305 + j*(164) -71 + j*(327) -210 + j*(6) --46 + j*(-25) -81 + j*(217) -372 + j*(-47) -49 + j*(-410) --353 + j*(-103) --105 + j*(274) -185 + j*(89) -45 + j*(-71) -21 + j*(68) -194 + j*(-9) -76 + j*(-224) --145 + j*(-120) --81 + j*(67) -43 + j*(45) -63 + j*(8) -141 + j*(-40) -125 + j*(-245) --159 + j*(-333) --387 + j*(-76) --262 + j*(242) -52 + j*(285) -228 + j*(51) -97 + j*(-194) --165 + j*(-156) --192 + j*(86) -6 + j*(148) -72 + j*(6) --21 + j*(-44) --42 + j*(8) --21 + j*(-8) --69 + j*(-26) --122 + j*(25) --125 + j*(115) --47 + j*(216) -127 + j*(212) -209 + j*(37) -93 + j*(-69) -43 + j*(0) -126 + j*(-35) -35 + j*(-187) --184 + j*(-109) --168 + j*(132) -25 + j*(175) -89 + j*(71) -62 + j*(46) -91 + j*(54) -129 + j*(8) -129 + j*(-59) -84 + j*(-127) --25 + j*(-149) --112 + j*(-56) --74 + j*(61) -32 + j*(75) -75 + j*(9) -45 + j*(-30) -35 + j*(-6) -99 + j*(-19) -99 + j*(-148) --78 + j*(-198) --180 + j*(-15) --16 + j*(105) -88 + j*(-45) --67 + j*(-121) --122 + j*(45) -47 + j*(96) -112 + j*(-54) -18 + j*(-138) --59 + j*(-147) --173 + j*(-126) --249 + j*(50) --78 + j*(206) -102 + j*(76) -4 + j*(-79) --115 + j*(8) --25 + j*(96) -45 + j*(4) --52 + j*(-67) --154 + j*(13) --117 + j*(154) -38 + j*(181) -104 + j*(40) --29 + j*(-26) --80 + j*(121) -78 + j*(172) -119 + j*(44) -52 + j*(59) -178 + j*(81) -203 + j*(-158) --105 + j*(-211) --176 + j*(105) -100 + j*(158) -86 + j*(-57) --78 + j*(70) -170 + j*(234) -381 + j*(-73) -115 + j*(-324) --103 + j*(-158) --21 + j*(-47) --13 + j*(-86) --24 + j*(-48) -26 + j*(-95) --98 + j*(-156) --170 + j*(23) -34 + j*(74) -33 + j*(-156) --228 + j*(-105) --163 + j*(162) -49 + j*(91) --55 + j*(-23) --78 + j*(143) -136 + j*(117) -88 + j*(-100) --74 + j*(-24) -45 + j*(58) -47 + j*(-107) --160 + j*(-49) --60 + j*(171) -133 + j*(49) --1 + j*(-78) --38 + j*(78) -146 + j*(24) -27 + j*(-180) --169 + j*(-9) -54 + j*(150) -183 + j*(-133) --143 + j*(-261) --291 + j*(56) --34 + j*(204) -76 + j*(14) --81 + j*(-49) --136 + j*(98) --8 + j*(189) -109 + j*(116) -85 + j*(4) --1 + j*(27) -54 + j*(110) -161 + j*(28) -81 + j*(-88) --9 + j*(-13) -81 + j*(32) -89 + j*(-84) --42 + j*(-56) -25 + j*(90) -211 + j*(2) -165 + j*(-228) --50 + j*(-291) --224 + j*(-180) --269 + j*(36) --84 + j*(199) -123 + j*(67) -13 + j*(-132) --170 + j*(-20) --52 + j*(141) -76 + j*(28) --49 + j*(-59) --116 + j*(81) -17 + j*(170) -146 + j*(95) -168 + j*(-48) -49 + j*(-161) --111 + j*(-78) --35 + j*(81) -108 + j*(-36) --85 + j*(-177) --255 + j*(91) -52 + j*(313) -323 + j*(22) -112 + j*(-261) --116 + j*(-156) --99 + j*(-52) --137 + j*(-53) --193 + j*(76) --76 + j*(194) -32 + j*(173) -106 + j*(176) -270 + j*(93) -274 + j*(-181) -8 + j*(-296) --151 + j*(-134) --101 + j*(-42) --129 + j*(-54) --191 + j*(64) --76 + j*(199) -84 + j*(156) -115 + j*(51) -105 + j*(1) -103 + j*(-62) -23 + j*(-135) --111 + j*(-93) --134 + j*(71) -18 + j*(165) -168 + j*(69) -170 + j*(-89) -86 + j*(-190) --62 + j*(-257) --286 + j*(-156) --298 + j*(162) -30 + j*(271) -175 + j*(-34) --128 + j*(-179) --298 + j*(134) --25 + j*(361) -221 + j*(213) -233 + j*(49) -245 + j*(-49) -184 + j*(-243) --98 + j*(-312) --303 + j*(-71) --190 + j*(200) -52 + j*(226) -160 + j*(67) -76 + j*(-42) -1 + j*(37) -141 + j*(112) -286 + j*(-86) -103 + j*(-325) --180 + j*(-226) --165 + j*(12) --15 + j*(30) --6 + j*(-50) --42 + j*(-57) --66 + j*(-71) --141 + j*(-52) --167 + j*(64) --81 + j*(138) --5 + j*(130) -53 + j*(117) -122 + j*(42) -70 + j*(-81) --72 + j*(-55) --62 + j*(87) -76 + j*(93) -98 + j*(-37) --18 + j*(-68) --57 + j*(47) -69 + j*(101) -165 + j*(-36) -36 + j*(-178) --132 + j*(-77) --51 + j*(88) -105 + j*(7) -21 + j*(-148) --135 + j*(-89) --132 + j*(34) --95 + j*(84) --34 + j*(168) -147 + j*(148) -190 + j*(-71) --7 + j*(-144) --42 + j*(10) -92 + j*(-43) --45 + j*(-206) --257 + j*(-30) --90 + j*(206) -115 + j*(66) --11 + j*(-71) --69 + j*(61) -85 + j*(42) --3 + j*(-151) --255 + j*(-30) --164 + j*(272) -136 + j*(253) -180 + j*(23) -35 + j*(-36) --21 + j*(70) -77 + j*(161) -246 + j*(105) -296 + j*(-127) -86 + j*(-293) --139 + j*(-175) --122 + j*(16) --23 + j*(62) -29 + j*(76) -148 + j*(69) -228 + j*(-103) -88 + j*(-265) --78 + j*(-213) --85 + j*(-136) --115 + j*(-165) --247 + j*(-107) --253 + j*(92) --76 + j*(185) -58 + j*(76) -3 + j*(-54) --125 + j*(-25) --125 + j*(115) -2 + j*(161) -76 + j*(91) -89 + j*(49) -140 + j*(-18) -88 + j*(-181) --148 + j*(-204) --255 + j*(20) --112 + j*(158) --23 + j*(98) --56 + j*(100) --4 + j*(156) -62 + j*(124) -68 + j*(116) -159 + j*(119) -223 + j*(-42) -63 + j*(-168) --75 + j*(-52) --2 + j*(51) -45 + j*(11) -22 + j*(23) -86 + j*(39) -112 + j*(-45) -52 + j*(-62) -90 + j*(-48) -91 + j*(-175) --97 + j*(-210) --167 + j*(-32) --47 + j*(19) --75 + j*(-48) --134 + j*(64) -28 + j*(141) -114 + j*(-26) --23 + j*(-104) --72 + j*(-25) --67 + j*(-39) --186 + j*(16) --132 + j*(243) -148 + j*(263) -255 + j*(40) -181 + j*(-93) -116 + j*(-193) --99 + j*(-260) --295 + j*(-11) --73 + j*(253) -186 + j*(70) -24 + j*(-122) --80 + j*(49) -122 + j*(68) -71 + j*(-155) --151 + j*(-36) -57 + j*(177) -284 + j*(-136) --108 + j*(-418) --460 + j*(-14) --102 + j*(373) -259 + j*(76) -0 + j*(-238) --278 + j*(4) --77 + j*(258) -132 + j*(125) -50 + j*(5) -30 + j*(89) -156 + j*(59) -136 + j*(-91) -25 + j*(-89) -60 + j*(-50) -67 + j*(-173) --136 + j*(-235) --296 + j*(-33) --186 + j*(202) -47 + j*(213) -152 + j*(32) -25 + j*(-130) --182 + j*(-38) --134 + j*(219) -156 + j*(234) -235 + j*(-38) -19 + j*(-140) --61 + j*(23) -84 + j*(67) -126 + j*(-87) --25 + j*(-165) --162 + j*(-55) --124 + j*(133) -90 + j*(179) -211 + j*(-38) -13 + j*(-212) --182 + j*(-48) --60 + j*(128) -51 + j*(36) --46 + j*(10) --1 + j*(147) -177 + j*(74) -106 + j*(-110) --42 + j*(-34) -55 + j*(71) -138 + j*(-32) -71 + j*(-79) -117 + j*(-62) -138 + j*(-248) --153 + j*(-356) --378 + j*(-59) --158 + j*(226) -103 + j*(93) -21 + j*(-108) --128 + j*(-50) --100 + j*(57) --52 + j*(62) --37 + j*(88) -56 + j*(103) -120 + j*(-14) -18 + j*(-119) --86 + j*(-52) --49 + j*(19) --28 + j*(-16) --78 + j*(4) --28 + j*(66) -40 + j*(-21) --94 + j*(-110) --235 + j*(46) --122 + j*(244) -82 + j*(224) -149 + j*(86) -103 + j*(-18) -2 + j*(-36) --35 + j*(56) -57 + j*(84) -52 + j*(-11) --54 + j*(59) -101 + j*(197) -290 + j*(-27) -21 + j*(-250) --200 + j*(57) -144 + j*(256) -317 + j*(-111) --35 + j*(-231) --62 + j*(93) -255 + j*(8) -97 + j*(-315) --196 + j*(-134) --5 + j*(62) -65 + j*(-169) --229 + j*(-138) --146 + j*(197) -177 + j*(89) -48 + j*(-173) --131 + j*(-8) -79 + j*(94) -136 + j*(-148) --89 + j*(-189) --98 + j*(-37) --33 + j*(-115) --235 + j*(-156) --340 + j*(135) --59 + j*(346) -229 + j*(163) -170 + j*(-139) --100 + j*(-177) --182 + j*(55) -35 + j*(134) -83 + j*(-104) --205 + j*(-132) --235 + j*(199) -92 + j*(236) -101 + j*(-49) --137 + j*(12) -4 + j*(226) -203 + j*(23) --34 + j*(-153) --190 + j*(95) -35 + j*(227) -117 + j*(71) -25 + j*(83) -146 + j*(158) -243 + j*(-14) -93 + j*(-117) -33 + j*(-8) -132 + j*(-5) -119 + j*(-95) -81 + j*(-100) -89 + j*(-154) --29 + j*(-220) --136 + j*(-104) --52 + j*(-29) --68 + j*(-131) --256 + j*(-42) --174 + j*(246) -167 + j*(237) -245 + j*(-77) -22 + j*(-215) --128 + j*(-107) --121 + j*(9) --64 + j*(64) -8 + j*(53) -4 + j*(-2) --37 + j*(31) -57 + j*(78) -134 + j*(-76) --64 + j*(-196) --221 + j*(20) --8 + j*(187) -134 + j*(-31) --113 + j*(-128) --178 + j*(175) -181 + j*(239) -266 + j*(-146) --107 + j*(-251) --209 + j*(91) -103 + j*(182) -199 + j*(-104) --37 + j*(-228) --179 + j*(-75) --117 + j*(39) --67 + j*(19) --123 + j*(6) --182 + j*(136) --29 + j*(314) -270 + j*(224) -297 + j*(-118) -5 + j*(-243) --147 + j*(-53) --59 + j*(62) --13 + j*(42) -6 + j*(65) -78 + j*(22) -16 + j*(-84) --120 + j*(-11) --54 + j*(141) -86 + j*(102) -69 + j*(6) -18 + j*(23) -39 + j*(59) -78 + j*(63) -129 + j*(35) -130 + j*(-42) -67 + j*(-43) -124 + j*(16) -233 + j*(-110) -101 + j*(-299) --107 + j*(-228) --93 + j*(-87) --44 + j*(-103) --73 + j*(-93) --12 + j*(-100) --74 + j*(-272) --402 + j*(-230) --477 + j*(182) --138 + j*(373) -49 + j*(196) --4 + j*(135) -72 + j*(177) -160 + j*(41) -48 + j*(-70) --42 + j*(-15) --48 + j*(32) --59 + j*(100) -64 + j*(181) -217 + j*(40) -97 + j*(-146) --69 + j*(-56) -16 + j*(49) -51 + j*(-58) --100 + j*(-43) --62 + j*(161) -190 + j*(142) -240 + j*(-128) -1 + j*(-267) --202 + j*(-106) --123 + j*(113) -81 + j*(69) -27 + j*(-138) --227 + j*(-65) --180 + j*(252) -156 + j*(284) -272 + j*(17) -142 + j*(-124) -55 + j*(-136) --46 + j*(-150) --151 + j*(-18) --26 + j*(148) -173 + j*(47) -125 + j*(-160) --49 + j*(-190) --146 + j*(-95) --146 + j*(23) --39 + j*(73) --4 + j*(-42) --192 + j*(-47) --214 + j*(250) -153 + j*(349) -335 + j*(-4) -52 + j*(-206) --117 + j*(13) -78 + j*(148) -223 + j*(-25) -107 + j*(-204) --91 + j*(-177) --137 + j*(24) -80 + j*(119) -240 + j*(-135) --16 + j*(-385) --337 + j*(-204) --276 + j*(81) --131 + j*(95) --144 + j*(98) --69 + j*(190) -58 + j*(122) -11 + j*(36) --13 + j*(97) -72 + j*(85) -51 + j*(5) -15 + j*(36) -71 + j*(20) -8 + j*(-52) --58 + j*(57) -110 + j*(100) -132 + j*(-136) --168 + j*(-152) --199 + j*(187) -130 + j*(242) -191 + j*(-30) --13 + j*(-49) -32 + j*(131) -248 + j*(64) -243 + j*(-201) --5 + j*(-322) --230 + j*(-169) --196 + j*(75) --16 + j*(98) --35 + j*(-2) --109 + j*(129) -127 + j*(247) -310 + j*(-20) -88 + j*(-214) --17 + j*(-38) -181 + j*(-79) -35 + j*(-376) --369 + j*(-230) --305 + j*(204) -51 + j*(236) -142 + j*(31) -117 + j*(-63) -76 + j*(-205) --181 + j*(-262) --340 + j*(21) --110 + j*(234) -94 + j*(80) --3 + j*(-83) --133 + j*(-50) --197 + j*(47) --180 + j*(219) -45 + j*(315) -223 + j*(128) -105 + j*(-37) -23 + j*(57) -156 + j*(66) -145 + j*(-112) --32 + j*(-117) --41 + j*(13) -35 + j*(-1) --9 + j*(-37) --20 + j*(28) -58 + j*(18) -37 + j*(-65) --47 + j*(-47) --27 + j*(33) -58 + j*(1) -15 + j*(-119) --175 + j*(-94) --216 + j*(169) -78 + j*(308) -295 + j*(36) -76 + j*(-201) --128 + j*(-14) -61 + j*(145) -202 + j*(-52) -37 + j*(-194) --88 + j*(-111) --111 + j*(-56) --168 + j*(45) --43 + j*(217) -190 + j*(112) -100 + j*(-115) --81 + j*(7) -115 + j*(171) -320 + j*(-76) -110 + j*(-345) --170 + j*(-251) --202 + j*(-48) --118 + j*(45) --31 + j*(53) -4 + j*(-3) --32 + j*(0) -56 + j*(38) -139 + j*(-158) --148 + j*(-346) --462 + j*(-49) --251 + j*(342) -106 + j*(250) -93 + j*(13) --2 + j*(1) --17 + j*(-29) --165 + j*(-13) --170 + j*(245) -145 + j*(297) -227 + j*(16) -27 + j*(-17) -124 + j*(132) -296 + j*(-95) -11 + j*(-325) --241 + j*(-57) --6 + j*(150) -126 + j*(-81) --124 + j*(-161) --195 + j*(89) -9 + j*(161) -58 + j*(30) --7 + j*(32) -46 + j*(65) -68 + j*(-27) --42 + j*(-48) --82 + j*(63) -6 + j*(127) -64 + j*(95) -73 + j*(83) -127 + j*(93) -195 + j*(22) -158 + j*(-81) -71 + j*(-58) -144 + j*(21) -292 + j*(-108) -192 + j*(-371) --107 + j*(-387) --221 + j*(-170) --129 + j*(-66) --102 + j*(-100) --140 + j*(-81) --131 + j*(-42) --135 + j*(-43) --150 + j*(-1) --105 + j*(19) --119 + j*(-37) --231 + j*(11) --203 + j*(185) --24 + j*(214) -26 + j*(82) --66 + j*(65) --45 + j*(161) -74 + j*(134) -50 + j*(-1) --112 + j*(23) --123 + j*(243) -134 + j*(355) -374 + j*(153) -311 + j*(-141) -69 + j*(-212) --59 + j*(-82) --23 + j*(46) -91 + j*(78) -191 + j*(-21) -141 + j*(-179) --24 + j*(-198) --78 + j*(-90) --41 + j*(-75) --111 + j*(-91) --164 + j*(45) --13 + j*(144) -105 + j*(21) -13 + j*(-90) --83 + j*(-31) --72 + j*(54) --16 + j*(114) -120 + j*(117) -209 + j*(-67) -25 + j*(-232) --168 + j*(-74) --19 + j*(94) -112 + j*(-90) --132 + j*(-218) --303 + j*(52) --74 + j*(267) -127 + j*(127) -59 + j*(10) -42 + j*(67) -127 + j*(27) -88 + j*(-70) -38 + j*(-35) -120 + j*(-59) -69 + j*(-244) --210 + j*(-252) --332 + j*(38) --124 + j*(254) -103 + j*(177) -129 + j*(16) -62 + j*(-56) --5 + j*(-55) --28 + j*(-5) -31 + j*(23) -71 + j*(-66) --43 + j*(-142) --154 + j*(-28) --56 + j*(91) -49 + j*(-14) --91 + j*(-120) --241 + j*(49) --97 + j*(265) -147 + j*(204) -175 + j*(4) -71 + j*(-74) -1 + j*(-69) --74 + j*(-44) --116 + j*(86) -41 + j*(211) -260 + j*(69) -173 + j*(-223) --151 + j*(-216) --218 + j*(95) -50 + j*(211) -184 + j*(-8) -11 + j*(-132) --96 + j*(4) -8 + j*(103) -95 + j*(48) -112 + j*(-3) -138 + j*(-74) -71 + j*(-193) --90 + j*(-191) --160 + j*(-76) --156 + j*(2) --149 + j*(106) -6 + j*(211) -207 + j*(63) -96 + j*(-185) --151 + j*(-116) --106 + j*(91) -28 + j*(43) --65 + j*(-14) --70 + j*(153) -167 + j*(157) -202 + j*(-108) --39 + j*(-171) --103 + j*(11) -18 + j*(47) -8 + j*(-15) --13 + j*(47) -106 + j*(54) -124 + j*(-97) --13 + j*(-128) --19 + j*(-32) -59 + j*(-93) --58 + j*(-210) --235 + j*(-93) --173 + j*(105) --12 + j*(91) --19 + j*(-16) --87 + j*(3) --59 + j*(40) --63 + j*(-13) --190 + j*(8) --238 + j*(218) --28 + j*(414) -288 + j*(330) -379 + j*(11) -155 + j*(-177) --21 + j*(-29) -142 + j*(110) -308 + j*(-112) -76 + j*(-364) --228 + j*(-204) --165 + j*(69) -11 + j*(55) --9 + j*(-9) -11 + j*(54) -137 + j*(-18) -57 + j*(-210) --174 + j*(-170) --202 + j*(40) --80 + j*(119) --4 + j*(99) -57 + j*(72) -91 + j*(-23) -2 + j*(-104) --105 + j*(-46) --95 + j*(64) --4 + j*(102) -67 + j*(42) -27 + j*(-38) --49 + j*(8) -37 + j*(84) -137 + j*(-60) --59 + j*(-211) --276 + j*(-4) --111 + j*(245) -100 + j*(150) -39 + j*(45) -44 + j*(131) -165 + j*(78) -103 + j*(-25) -91 + j*(86) -328 + j*(23) -293 + j*(-351) --117 + j*(-438) --303 + j*(-141) --199 + j*(38) --134 + j*(95) -3 + j*(163) -148 + j*(17) -15 + j*(-133) --74 + j*(6) -112 + j*(-8) -0 + j*(-288) --395 + j*(-139) --284 + j*(327) -161 + j*(292) -171 + j*(-38) --12 + j*(-35) -43 + j*(32) -42 + j*(-57) --28 + j*(-5) -96 + j*(-1) -39 + j*(-228) --286 + j*(-150) --209 + j*(217) -135 + j*(122) --25 + j*(-186) --325 + j*(42) --75 + j*(346) -185 + j*(126) --11 + j*(-35) --67 + j*(190) -208 + j*(199) -223 + j*(-86) --15 + j*(-120) --46 + j*(49) -71 + j*(74) -103 + j*(-5) -66 + j*(-67) --37 + j*(-75) --94 + j*(66) -62 + j*(173) -192 + j*(35) -88 + j*(-50) -105 + j*(66) -313 + j*(-35) -223 + j*(-352) --117 + j*(-362) --214 + j*(-116) --118 + j*(-18) --79 + j*(3) -4 + j*(16) -34 + j*(-110) --133 + j*(-130) --123 + j*(67) -101 + j*(-2) --35 + j*(-277) --377 + j*(-114) --243 + j*(260) -86 + j*(173) -13 + j*(-74) --164 + j*(1) --120 + j*(128) --76 + j*(166) -41 + j*(252) -271 + j*(109) -152 + j*(-218) --205 + j*(-132) --139 + j*(202) -138 + j*(141) -63 + j*(-48) --29 + j*(73) -163 + j*(103) -194 + j*(-156) --71 + j*(-252) --256 + j*(-65) --218 + j*(179) -21 + j*(313) -284 + j*(127) -158 + j*(-184) --140 + j*(-66) -32 + j*(200) -288 + j*(-52) --25 + j*(-322) --303 + j*(11) -8 + j*(266) -199 + j*(1) --21 + j*(-95) --13 + j*(100) -170 + j*(16) -52 + j*(-146) --64 + j*(-15) -80 + j*(44) -100 + j*(-100) --12 + j*(-95) -40 + j*(-29) -87 + j*(-139) --32 + j*(-217) --127 + j*(-185) --219 + j*(-163) --351 + j*(-13) --260 + j*(244) -8 + j*(251) -52 + j*(61) --82 + j*(55) --55 + j*(198) -103 + j*(207) -172 + j*(102) -163 + j*(34) -175 + j*(-6) -187 + j*(-92) -112 + j*(-191) --13 + j*(-187) --48 + j*(-117) --37 + j*(-129) --129 + j*(-146) --194 + j*(-21) --95 + j*(64) --56 + j*(-2) --133 + j*(26) --59 + j*(139) -74 + j*(41) --53 + j*(-100) --219 + j*(56) --78 + j*(266) -144 + j*(188) -136 + j*(12) -25 + j*(2) -35 + j*(95) -173 + j*(95) -249 + j*(-93) -69 + j*(-274) --174 + j*(-158) --117 + j*(83) -91 + j*(48) -60 + j*(-139) --109 + j*(-133) --146 + j*(-28) --153 + j*(18) --174 + j*(133) --21 + j*(262) -191 + j*(147) -131 + j*(-84) --91 + j*(-60) --91 + j*(168) -141 + j*(219) -254 + j*(37) -179 + j*(-83) -151 + j*(-97) -132 + j*(-204) --59 + j*(-262) --197 + j*(-70) --52 + j*(82) -57 + j*(-21) --24 + j*(-64) -4 + j*(2) -58 + j*(-95) --100 + j*(-137) --112 + j*(71) -148 + j*(45) -110 + j*(-274) --224 + j*(-282) --287 + j*(-44) --231 + j*(-8) --341 + j*(89) --217 + j*(372) -134 + j*(326) -149 + j*(50) -1 + j*(65) -110 + j*(130) -159 + j*(-41) --1 + j*(-98) --35 + j*(-6) --40 + j*(-34) --161 + j*(46) --49 + j*(272) -239 + j*(190) -215 + j*(-86) -18 + j*(-94) -22 + j*(13) -71 + j*(-9) -58 + j*(-19) -90 + j*(-33) -60 + j*(-100) --13 + j*(-57) -71 + j*(-2) -117 + j*(-132) --30 + j*(-194) --86 + j*(-75) --5 + j*(-81) -138 + j*(169) -171 + j*(-16) -31 + j*(-37) -76 + j*(78) -231 + j*(-36) -105 + j*(-274) --192 + j*(-209) --205 + j*(77) -11 + j*(123) -16 + j*(-23) --105 + j*(62) -64 + j*(218) -275 + j*(9) -74 + j*(-238) --168 + j*(-60) --8 + j*(139) -133 + j*(-11) --16 + j*(-84) --25 + j*(78) -161 + j*(52) -138 + j*(-136) --6 + j*(-127) -21 + j*(-45) -83 + j*(-111) -18 + j*(-208) --103 + j*(-223) --221 + j*(-151) --252 + j*(-1) --166 + j*(93) --98 + j*(93) --58 + j*(98) --4 + j*(57) --63 + j*(-6) --138 + j*(103) -16 + j*(211) -146 + j*(52) -10 + j*(-53) --27 + j*(73) -110 + j*(28) --1 + j*(-129) --175 + j*(21) --14 + j*(196) -130 + j*(52) -11 + j*(-21) -27 + j*(103) -193 + j*(16) -107 + j*(-202) --131 + j*(-188) --225 + j*(0) --151 + j*(190) -72 + j*(253) -236 + j*(65) -118 + j*(-120) -0 + j*(-57) -58 + j*(-48) --39 + j*(-142) --183 + j*(23) -5 + j*(203) -180 + j*(36) -63 + j*(-68) -97 + j*(18) -214 + j*(-175) --72 + j*(-381) --351 + j*(-119) --185 + j*(129) --79 + j*(41) --179 + j*(95) --40 + j*(252) -127 + j*(124) -24 + j*(40) -58 + j*(175) -269 + j*(78) -195 + j*(-171) -1 + j*(-156) --3 + j*(-79) --44 + j*(-112) --129 + j*(-7) --21 + j*(110) -84 + j*(32) -48 + j*(-4) -119 + j*(15) -174 + j*(-157) --36 + j*(-284) --210 + j*(-117) --117 + j*(38) --27 + j*(-5) --57 + j*(-45) --81 + j*(-31) --107 + j*(-19) --129 + j*(36) --92 + j*(88) --56 + j*(98) --28 + j*(129) -60 + j*(140) -129 + j*(58) -108 + j*(-37) -47 + j*(-77) --11 + j*(-66) --13 + j*(-17) -44 + j*(-52) --26 + j*(-168) --223 + j*(-115) --238 + j*(111) --64 + j*(192) -21 + j*(105) --16 + j*(61) --45 + j*(96) --6 + j*(173) -145 + j*(181) -225 + j*(-13) -28 + j*(-133) --81 + j*(72) -163 + j*(156) -250 + j*(-125) --13 + j*(-226) --88 + j*(-43) -2 + j*(-64) --158 + j*(-110) --231 + j*(163) -66 + j*(300) -243 + j*(77) -145 + j*(-66) -91 + j*(-82) --3 + j*(-118) --97 + j*(46) -150 + j*(188) -357 + j*(-127) -28 + j*(-403) --263 + j*(-116) --34 + j*(139) -162 + j*(-49) -13 + j*(-190) --71 + j*(-94) --10 + j*(-69) --17 + j*(-113) --30 + j*(-117) --39 + j*(-168) --137 + j*(-205) --234 + j*(-144) --278 + j*(-71) --324 + j*(36) --268 + j*(194) --107 + j*(233) --40 + j*(147) --77 + j*(115) --82 + j*(144) --68 + j*(184) -1 + j*(250) -151 + j*(223) -182 + j*(59) -47 + j*(4) -1 + j*(134) -144 + j*(217) -321 + j*(108) -336 + j*(-132) -124 + j*(-289) --108 + j*(-170) --71 + j*(62) -132 + j*(80) -207 + j*(-77) -137 + j*(-212) --21 + j*(-270) --189 + j*(-154) --143 + j*(55) -40 + j*(48) -29 + j*(-76) --23 + j*(-30) -86 + j*(-61) --16 + j*(-259) --301 + j*(-136) --191 + j*(176) -76 + j*(64) --82 + j*(-138) --248 + j*(69) --47 + j*(208) -20 + j*(65) --73 + j*(123) -99 + j*(208) -180 + j*(-16) --52 + j*(-37) -25 + j*(211) -308 + j*(54) -112 + j*(-242) --138 + j*(-21) -132 + j*(167) -282 + j*(-146) --18 + j*(-290) --132 + j*(-64) --1 + j*(-25) --52 + j*(-86) --66 + j*(31) -93 + j*(6) -41 + j*(-172) --129 + j*(-120) --83 + j*(-8) --58 + j*(-74) --164 + j*(-30) --86 + j*(102) -34 + j*(-6) --129 + j*(-104) --228 + j*(110) --2 + j*(228) -122 + j*(19) --69 + j*(-95) --194 + j*(75) --91 + j*(233) -55 + j*(252) -185 + j*(220) -327 + j*(85) -330 + j*(-186) -59 + j*(-378) --275 + j*(-226) --273 + j*(152) -69 + j*(266) -235 + j*(-11) -22 + j*(-172) --91 + j*(0) -83 + j*(44) -72 + j*(-172) --193 + j*(-160) --221 + j*(110) --21 + j*(165) --10 + j*(71) --45 + j*(179) -176 + j*(250) -351 + j*(4) -187 + j*(-248) --58 + j*(-215) --134 + j*(-49) --70 + j*(90) -96 + j*(116) -197 + j*(-52) -59 + j*(-202) --98 + j*(-122) --70 + j*(-14) --54 + j*(-15) --69 + j*(80) -129 + j*(153) -303 + j*(-96) -85 + j*(-378) --241 + j*(-274) --278 + j*(-6) --146 + j*(123) -7 + j*(137) -139 + j*(-3) -30 + j*(-230) --274 + j*(-177) --313 + j*(152) --42 + j*(278) -115 + j*(126) -76 + j*(6) -21 + j*(-25) --47 + j*(-20) --79 + j*(77) -37 + j*(151) -155 + j*(52) -115 + j*(-82) -19 + j*(-114) --53 + j*(-88) --88 + j*(-23) --47 + j*(28) --21 + j*(-10) --91 + j*(-20) --108 + j*(88) -8 + j*(125) -48 + j*(22) --56 + j*(-13) --115 + j*(101) --33 + j*(222) -136 + j*(245) -288 + j*(110) -260 + j*(-110) -67 + j*(-175) --20 + j*(-52) -64 + j*(-1) -83 + j*(-84) --3 + j*(-98) --11 + j*(-27) -53 + j*(-38) -29 + j*(-122) --88 + j*(-127) --158 + j*(-10) --103 + j*(127) -46 + j*(177) -194 + j*(92) -219 + j*(-91) -73 + j*(-203) --47 + j*(-112) -50 + j*(-37) -113 + j*(-226) --173 + j*(-369) --459 + j*(-75) --267 + j*(309) -103 + j*(266) -158 + j*(7) -39 + j*(-69) --4 + j*(-54) --42 + j*(-57) --64 + j*(-7) --15 + j*(-8) --68 + j*(-75) --190 + j*(26) --75 + j*(214) -159 + j*(127) -119 + j*(-120) --113 + j*(-125) --154 + j*(73) --1 + j*(133) -53 + j*(23) --35 + j*(-5) --37 + j*(91) -76 + j*(78) -54 + j*(-48) --77 + j*(-11) --22 + j*(120) -104 + j*(47) -5 + j*(-65) --92 + j*(55) -28 + j*(141) -81 + j*(59) -44 + j*(87) -179 + j*(117) -244 + j*(-84) -56 + j*(-171) -18 + j*(-42) -110 + j*(-112) --64 + j*(-203) --151 + j*(35) -129 + j*(78) -115 + j*(-264) --286 + j*(-228) --276 + j*(174) -35 + j*(175) --31 + j*(3) --115 + j*(204) -204 + j*(310) -392 + j*(-6) -218 + j*(-228) -87 + j*(-224) -16 + j*(-268) --153 + j*(-245) --214 + j*(-83) --144 + j*(-13) --146 + j*(-17) --177 + j*(42) --155 + j*(139) --41 + j*(238) -184 + j*(183) -202 + j*(-103) --98 + j*(-148) --96 + j*(172) -290 + j*(103) -187 + j*(-378) --361 + j*(-303) --335 + j*(233) -112 + j*(228) -70 + j*(-117) --220 + j*(-16) --105 + j*(269) -175 + j*(218) -240 + j*(-1) -139 + j*(-170) --76 + j*(-202) --206 + j*(-1) --41 + j*(163) -97 + j*(21) --49 + j*(-71) --110 + j*(96) -61 + j*(147) -104 + j*(8) -9 + j*(-8) -31 + j*(57) -87 + j*(23) -74 + j*(-18) -83 + j*(-41) -50 + j*(-121) --93 + j*(-125) --170 + j*(37) --49 + j*(194) -160 + j*(169) -248 + j*(-33) -101 + j*(-201) --77 + j*(-106) -16 + j*(42) -153 + j*(-100) --37 + j*(-273) --260 + j*(-90) --132 + j*(139) -43 + j*(68) --6 + j*(-21) --18 + j*(41) -70 + j*(1) --1 + j*(-109) --128 + j*(-21) --35 + j*(126) -136 + j*(49) -116 + j*(-148) --77 + j*(-223) --245 + j*(-94) --228 + j*(111) --66 + j*(186) -25 + j*(107) --4 + j*(63) --1 + j*(93) -39 + j*(82) -38 + j*(65) -63 + j*(76) -94 + j*(30) -45 + j*(6) -70 + j*(89) -226 + j*(30) -187 + j*(-206) --70 + j*(-217) --106 + j*(1) -54 + j*(12) -25 + j*(-103) --43 + j*(-42) -50 + j*(-44) --26 + j*(-195) --242 + j*(-65) --86 + j*(187) -168 + j*(5) --59 + j*(-237) --286 + j*(36) -18 + j*(249) -221 + j*(-82) --111 + j*(-298) --361 + j*(-28) --236 + j*(218) --90 + j*(258) -46 + j*(279) -197 + j*(146) -99 + j*(-45) --68 + j*(61) -70 + j*(210) -206 + j*(71) -90 + j*(-3) -121 + j*(132) -343 + j*(42) -306 + j*(-258) -44 + j*(-334) --93 + j*(-221) --117 + j*(-137) --129 + j*(-74) --117 + j*(-31) --138 + j*(6) --113 + j*(123) -61 + j*(161) -150 + j*(2) -51 + j*(-83) -28 + j*(-44) -50 + j*(-108) --72 + j*(-148) --126 + j*(-25) --35 + j*(-13) --116 + j*(-93) --243 + j*(79) --44 + j*(286) -213 + j*(133) -146 + j*(-103) --11 + j*(-98) --22 + j*(-30) --7 + j*(-33) --11 + j*(-42) --28 + j*(-73) --112 + j*(-69) --141 + j*(33) --66 + j*(71) --74 + j*(28) --130 + j*(108) --23 + j*(220) -121 + j*(146) -100 + j*(47) -80 + j*(74) -177 + j*(49) -192 + j*(-122) -4 + j*(-225) --177 + j*(-88) --115 + j*(122) -74 + j*(116) -81 + j*(-32) --33 + j*(-11) -33 + j*(89) -124 + j*(-4) -15 + j*(-59) -33 + j*(91) -272 + j*(5) -190 + j*(-344) --204 + j*(-337) --279 + j*(-7) --79 + j*(77) --61 + j*(-11) --98 + j*(45) --18 + j*(73) --5 + j*(12) --30 + j*(23) --7 + j*(-3) --117 + j*(-27) --175 + j*(190) -113 + j*(332) -339 + j*(58) -153 + j*(-180) --6 + j*(-69) -95 + j*(-9) -112 + j*(-137) -5 + j*(-180) --50 + j*(-175) --165 + j*(-189) --298 + j*(-45) --235 + j*(155) --98 + j*(201) --30 + j*(216) -103 + j*(233) -236 + j*(89) -165 + j*(-84) -43 + j*(-76) -48 + j*(-39) -39 + j*(-93) --65 + j*(-92) --103 + j*(33) -16 + j*(115) -131 + j*(11) -40 + j*(-123) --109 + j*(-20) -25 + j*(151) -238 + j*(-4) -93 + j*(-249) --129 + j*(-137) --25 + j*(4) -26 + j*(-148) --188 + j*(-151) --175 + j*(78) -18 + j*(22) --127 + j*(-142) --316 + j*(84) --95 + j*(322) -147 + j*(190) -126 + j*(31) -100 + j*(-28) -6 + j*(-132) --205 + j*(-31) --122 + j*(247) -168 + j*(197) -136 + j*(-45) --29 + j*(11) -76 + j*(120) -163 + j*(-8) -53 + j*(-73) -34 + j*(-1) -80 + j*(-33) -23 + j*(-58) -38 + j*(-1) -97 + j*(-74) --21 + j*(-153) --113 + j*(-23) --6 + j*(59) -35 + j*(-18) --14 + j*(3) -79 + j*(45) -146 + j*(-105) --11 + j*(-223) --163 + j*(-120) --147 + j*(15) --73 + j*(63) --5 + j*(44) --18 + j*(-26) --122 + j*(21) --46 + j*(200) -216 + j*(142) -220 + j*(-159) --49 + j*(-223) --127 + j*(-42) --32 + j*(-11) --76 + j*(-63) --124 + j*(33) --28 + j*(82) --2 + j*(9) --49 + j*(31) -21 + j*(60) -26 + j*(-55) --136 + j*(-30) --95 + j*(194) -192 + j*(163) -202 + j*(-169) --139 + j*(-247) --292 + j*(45) --106 + j*(243) -64 + j*(181) -78 + j*(105) -98 + j*(102) -156 + j*(51) -143 + j*(-47) -60 + j*(-82) -14 + j*(-37) -42 + j*(-9) -54 + j*(-51) --11 + j*(-55) --8 + j*(37) -132 + j*(31) -141 + j*(-167) --99 + j*(-227) --214 + j*(21) -16 + j*(170) -176 + j*(-35) -1 + j*(-192) --143 + j*(-53) --38 + j*(50) -16 + j*(-36) --76 + j*(-49) --75 + j*(47) -4 + j*(50) -15 + j*(9) -35 + j*(7) -62 + j*(-85) --89 + j*(-181) --284 + j*(-24) --200 + j*(250) -75 + j*(296) -235 + j*(119) -209 + j*(-78) -54 + j*(-180) --109 + j*(-104) --86 + j*(60) -50 + j*(40) --7 + j*(-86) --163 + j*(18) --50 + j*(236) -219 + j*(178) -261 + j*(-81) -93 + j*(-204) --46 + j*(-151) --62 + j*(-53) -9 + j*(-37) --6 + j*(-150) --204 + j*(-142) --251 + j*(129) -44 + j*(235) -179 + j*(-49) --92 + j*(-185) --224 + j*(63) --23 + j*(180) -44 + j*(37) --61 + j*(49) -11 + j*(160) -138 + j*(74) -73 + j*(-49) --30 + j*(-4) --8 + j*(94) -106 + j*(132) -247 + j*(18) -187 + j*(-228) --112 + j*(-264) --233 + j*(19) --22 + j*(182) -129 + j*(60) -98 + j*(-37) -78 + j*(-68) -28 + j*(-122) --53 + j*(-83) --20 + j*(-33) --34 + j*(-88) --128 + j*(-16) --5 + j*(105) -121 + j*(-70) --107 + j*(-190) --213 + j*(73) -61 + j*(124) -12 + j*(-165) --330 + j*(-8) --106 + j*(413) -366 + j*(186) -166 + j*(-272) --235 + j*(-93) --61 + j*(252) -247 + j*(101) -165 + j*(-173) --52 + j*(-185) --144 + j*(-51) --87 + j*(78) -44 + j*(53) --8 + j*(-77) --158 + j*(33) --1 + j*(223) -214 + j*(47) -35 + j*(-146) --105 + j*(49) -132 + j*(135) -194 + j*(-134) --62 + j*(-203) --132 + j*(-12) --42 + j*(33) --53 + j*(45) -37 + j*(127) -180 + j*(4) -67 + j*(-156) --43 + j*(-66) -58 + j*(-57) --21 + j*(-222) --253 + j*(-117) --170 + j*(121) -4 + j*(33) --148 + j*(-78) --264 + j*(141) --60 + j*(298) -76 + j*(199) -69 + j*(198) -254 + j*(226) -409 + j*(-74) -118 + j*(-368) --250 + j*(-156) --117 + j*(216) -229 + j*(144) -211 + j*(-153) -4 + j*(-170) -17 + j*(-78) -25 + j*(-194) --210 + j*(-213) --315 + j*(76) --71 + j*(266) -132 + j*(136) -108 + j*(-1) -71 + j*(-26) -48 + j*(-62) --4 + j*(-49) -31 + j*(-17) -52 + j*(-103) --76 + j*(-139) --118 + j*(-13) --18 + j*(-8) --95 + j*(-107) --242 + j*(40) --76 + j*(244) -146 + j*(102) -25 + j*(-105) --175 + j*(8) --96 + j*(219) -109 + j*(235) -243 + j*(102) -238 + j*(-103) -35 + j*(-230) --175 + j*(-71) --66 + j*(175) -197 + j*(110) -174 + j*(-141) --46 + j*(-141) --14 + j*(55) -214 + j*(-29) -127 + j*(-362) --308 + j*(-368) --463 + j*(72) --127 + j*(339) -137 + j*(142) -37 + j*(-33) --33 + j*(45) -71 + j*(40) -31 + j*(-100) --148 + j*(-56) --133 + j*(151) -80 + j*(188) -175 + j*(-13) --8 + j*(-161) --218 + j*(16) --62 + j*(306) -307 + j*(204) -282 + j*(-192) --77 + j*(-222) --102 + j*(70) -148 + j*(46) -76 + j*(-195) --163 + j*(-113) --102 + j*(98) -49 + j*(60) -26 + j*(-11) -32 + j*(3) -41 + j*(-80) --122 + j*(-91) --158 + j*(142) -111 + j*(235) -263 + j*(-9) -100 + j*(-180) --24 + j*(-112) --10 + j*(-76) --56 + j*(-92) --91 + j*(-4) -8 + j*(40) -39 + j*(-65) --73 + j*(-80) --68 + j*(33) -44 + j*(-6) --33 + j*(-130) --175 + j*(-30) --64 + j*(118) -66 + j*(-15) --110 + j*(-141) --264 + j*(64) --81 + j*(255) -96 + j*(142) -45 + j*(30) -16 + j*(57) -28 + j*(26) --52 + j*(40) --20 + j*(188) -189 + j*(180) -245 + j*(-30) -107 + j*(-127) -26 + j*(-82) -10 + j*(-51) -16 + j*(-8) -87 + j*(-27) -52 + j*(-146) --113 + j*(-113) --96 + j*(65) -66 + j*(48) -40 + j*(-81) --51 + j*(-44) --7 + j*(-4) --27 + j*(-67) --122 + j*(-4) --56 + j*(119) -57 + j*(86) -60 + j*(37) -102 + j*(34) -138 + j*(-71) -28 + j*(-156) --66 + j*(-100) --81 + j*(-52) --119 + j*(24) --2 + j*(164) -234 + j*(32) -120 + j*(-280) --211 + j*(-208) --163 + j*(80) -48 + j*(6) --82 + j*(-158) --237 + j*(8) --83 + j*(151) -16 + j*(23) --105 + j*(-33) --162 + j*(88) --88 + j*(173) --7 + j*(180) -49 + j*(146) -41 + j*(116) -52 + j*(172) -192 + j*(187) -280 + j*(25) -190 + j*(-87) -165 + j*(-76) -192 + j*(-189) -2 + j*(-319) --212 + j*(-167) --150 + j*(40) --28 + j*(29) --51 + j*(-14) --64 + j*(33) --37 + j*(63) --5 + j*(105) -121 + j*(116) -203 + j*(-59) -33 + j*(-202) --124 + j*(-63) --6 + j*(66) -93 + j*(-57) --46 + j*(-152) --161 + j*(-16) --57 + j*(126) -104 + j*(80) -132 + j*(-82) -4 + j*(-183) --140 + j*(-127) --165 + j*(3) --103 + j*(65) --59 + j*(71) --27 + j*(72) --1 + j*(49) --18 + j*(29) --30 + j*(56) --1 + j*(76) -23 + j*(69) -44 + j*(73) -88 + j*(52) -102 + j*(-11) -66 + j*(-52) -34 + j*(-64) --6 + j*(-72) --51 + j*(-47) --64 + j*(-3) --70 + j*(43) --40 + j*(127) -103 + j*(165) -236 + j*(36) -203 + j*(-141) -91 + j*(-225) --43 + j*(-272) --245 + j*(-207) --314 + j*(58) --100 + j*(226) -71 + j*(105) -6 + j*(12) -8 + j*(86) -137 + j*(24) -72 + j*(-169) --155 + j*(-161) --243 + j*(38) --152 + j*(206) -35 + j*(274) -239 + j*(147) -209 + j*(-130) --77 + j*(-184) --187 + j*(78) -30 + j*(220) -177 + j*(68) -86 + j*(-40) -37 + j*(33) -138 + j*(57) -199 + j*(-63) -119 + j*(-182) --6 + j*(-187) --65 + j*(-117) --58 + j*(-79) --84 + j*(-76) --130 + j*(1) --47 + j*(105) -95 + j*(50) -74 + j*(-98) --52 + j*(-102) --61 + j*(-11) -1 + j*(-19) --22 + j*(-62) --42 + j*(-39) --13 + j*(-65) --95 + j*(-143) --254 + j*(-52) --218 + j*(170) --1 + j*(207) -68 + j*(42) --62 + j*(-22) --127 + j*(99) --28 + j*(198) -100 + j*(168) -161 + j*(67) -137 + j*(-53) -23 + j*(-115) --88 + j*(-56) --102 + j*(47) --71 + j*(115) --13 + j*(189) -136 + j*(218) -274 + j*(76) -213 + j*(-101) -94 + j*(-103) -122 + j*(-74) -119 + j*(-194) --63 + j*(-236) --153 + j*(-74) --51 + j*(-9) --75 + j*(-94) --219 + j*(11) --104 + j*(242) -171 + j*(182) -173 + j*(-53) -30 + j*(-60) -84 + j*(1) -123 + j*(-148) --86 + j*(-216) --199 + j*(-1) --18 + j*(121) -79 + j*(-26) --52 + j*(-82) --74 + j*(56) -83 + j*(62) -101 + j*(-119) --90 + j*(-180) --211 + j*(-8) --95 + j*(165) -104 + j*(121) -125 + j*(-66) --21 + j*(-136) --109 + j*(-46) --74 + j*(21) --54 + j*(21) --50 + j*(49) -8 + j*(59) -33 + j*(-11) --33 + j*(-55) --105 + j*(-14) --122 + j*(79) --34 + j*(183) -147 + j*(138) -163 + j*(-91) --69 + j*(-154) --146 + j*(50) -21 + j*(95) --13 + j*(-51) --182 + j*(74) --1 + j*(296) -258 + j*(112) -97 + j*(-134) --93 + j*(26) -86 + j*(161) -185 + j*(-30) -3 + j*(-100) --35 + j*(62) -97 + j*(78) -108 + j*(9) -132 + j*(20) -209 + j*(-88) -66 + j*(-243) --126 + j*(-114) --15 + j*(74) -154 + j*(-27) -83 + j*(-182) --23 + j*(-168) --54 + j*(-163) --157 + j*(-145) --198 + j*(7) --65 + j*(86) --8 + j*(4) --59 + j*(11) -16 + j*(64) -93 + j*(-59) --44 + j*(-173) --175 + j*(-67) --128 + j*(35) --103 + j*(34) --101 + j*(98) -22 + j*(112) -37 + j*(-44) --161 + j*(-40) --138 + j*(218) -171 + j*(208) -193 + j*(-130) --136 + j*(-187) --226 + j*(96) --24 + j*(198) -43 + j*(97) -25 + j*(105) -112 + j*(83) -74 + j*(-59) --106 + j*(-1) --40 + j*(228) -238 + j*(198) -291 + j*(-81) -85 + j*(-223) --102 + j*(-134) --134 + j*(42) --7 + j*(164) -153 + j*(119) -189 + j*(-5) -176 + j*(-74) -160 + j*(-194) --38 + j*(-299) --253 + j*(-97) --90 + j*(166) -163 + j*(25) -18 + j*(-195) --168 + j*(-37) -6 + j*(115) -129 + j*(-74) --57 + j*(-192) --192 + j*(-52) --152 + j*(83) --61 + j*(173) -138 + j*(174) -239 + j*(-86) --32 + j*(-259) --235 + j*(6) -30 + j*(211) -244 + j*(-52) -16 + j*(-287) --218 + j*(-146) --188 + j*(21) --148 + j*(50) --149 + j*(127) --40 + j*(220) -122 + j*(177) -188 + j*(19) -91 + j*(-129) --91 + j*(-100) --105 + j*(88) -85 + j*(121) -137 + j*(-74) --48 + j*(-150) --143 + j*(8) --28 + j*(99) -43 + j*(16) --33 + j*(-38) --91 + j*(52) -11 + j*(128) -108 + j*(16) --25 + j*(-107) --197 + j*(54) --35 + j*(287) -231 + j*(175) -180 + j*(-54) -37 + j*(-19) -104 + j*(53) -146 + j*(-32) -103 + j*(-37) -197 + j*(-47) -201 + j*(-274) --88 + j*(-373) --273 + j*(-151) --202 + j*(18) --151 + j*(68) --64 + j*(161) -115 + j*(89) -55 + j*(-106) --114 + j*(-28) -2 + j*(107) -102 + j*(-45) --75 + j*(-107) --86 + j*(72) -73 + j*(25) --35 + j*(-103) --129 + j*(71) -110 + j*(129) -143 + j*(-177) --216 + j*(-223) --318 + j*(144) --21 + j*(317) -190 + j*(157) -169 + j*(-28) -50 + j*(-92) --35 + j*(-16) -55 + j*(55) -124 + j*(-91) --76 + j*(-184) --195 + j*(43) -23 + j*(168) -127 + j*(-21) --24 + j*(-86) --48 + j*(16) --13 + j*(1) --77 + j*(50) -61 + j*(185) -277 + j*(-13) -76 + j*(-301) --230 + j*(-147) --134 + j*(109) -17 + j*(51) --36 + j*(18) -34 + j*(83) -119 + j*(-69) --88 + j*(-181) --231 + j*(35) --56 + j*(187) -56 + j*(81) -0 + j*(47) -33 + j*(84) -54 + j*(20) --30 + j*(49) -67 + j*(183) -291 + j*(59) -209 + j*(-247) --123 + j*(-255) --218 + j*(47) -18 + j*(204) -210 + j*(45) -127 + j*(-150) --28 + j*(-127) --19 + j*(-28) -41 + j*(-64) --23 + j*(-112) --67 + j*(-49) --11 + j*(-40) --58 + j*(-117) --178 + j*(-32) --90 + j*(123) -77 + j*(41) --18 + j*(-128) --199 + j*(-32) --130 + j*(159) -25 + j*(129) -2 + j*(50) --11 + j*(135) -169 + j*(147) -255 + j*(-99) -20 + j*(-288) --238 + j*(-140) --201 + j*(104) --42 + j*(139) --18 + j*(82) --24 + j*(129) -86 + j*(163) -189 + j*(54) -141 + j*(-90) -16 + j*(-121) --60 + j*(-47) --37 + j*(35) -34 + j*(42) -54 + j*(-21) -1 + j*(-56) --64 + j*(-23) --86 + j*(66) --4 + j*(176) -185 + j*(168) -293 + j*(-25) -189 + j*(-211) -37 + j*(-234) --41 + j*(-211) --153 + j*(-193) --257 + j*(-36) --156 + j*(163) -59 + j*(153) -124 + j*(-12) -31 + j*(-100) --38 + j*(-74) --36 + j*(-50) --52 + j*(-71) --115 + j*(-49) --112 + j*(33) --35 + j*(22) --97 + j*(-69) --265 + j*(47) --158 + j*(327) -183 + j*(303) -255 + j*(-6) -49 + j*(-117) --35 + j*(-29) --37 + j*(-11) --100 + j*(52) --19 + j*(184) -144 + j*(127) -116 + j*(0) -74 + j*(40) -171 + j*(14) -134 + j*(-144) --31 + j*(-127) --19 + j*(-9) -37 + j*(-53) --46 + j*(-69) --46 + j*(33) -40 + j*(25) -20 + j*(-9) -61 + j*(40) -169 + j*(-71) -25 + j*(-241) --170 + j*(-106) --41 + j*(49) -47 + j*(-108) --164 + j*(-161) --221 + j*(74) --23 + j*(134) -0 + j*(1) --84 + j*(45) -12 + j*(110) -64 + j*(-10) --69 + j*(-43) --93 + j*(108) -71 + j*(156) -163 + j*(8) -57 + j*(-125) --102 + j*(-61) --56 + j*(121) -161 + j*(79) -127 + j*(-186) --178 + j*(-166) --173 + j*(155) -146 + j*(148) -126 + j*(-161) --166 + j*(-127) --125 + j*(134) -91 + j*(84) -23 + j*(-89) --124 + j*(-6) --51 + j*(129) -67 + j*(97) -84 + j*(18) -59 + j*(-33) -6 + j*(-53) --37 + j*(-18) --30 + j*(18) --25 + j*(32) --8 + j*(62) -33 + j*(58) -24 + j*(46) -67 + j*(115) -241 + j*(51) -215 + j*(-228) --107 + j*(-264) --177 + j*(41) -102 + j*(90) -109 + j*(-188) --174 + j*(-182) --178 + j*(73) -10 + j*(71) --40 + j*(-48) --136 + j*(58) --13 + j*(171) -109 + j*(90) -91 + j*(7) -77 + j*(-2) -96 + j*(-32) -83 + j*(-88) -29 + j*(-134) --59 + j*(-119) --66 + j*(-29) -28 + j*(-53) --49 + j*(-205) --292 + j*(-125) --271 + j*(165) --31 + j*(194) --34 + j*(57) --119 + j*(175) -101 + j*(296) -293 + j*(71) -163 + j*(-140) -30 + j*(-122) --22 + j*(-136) --182 + j*(-74) --144 + j*(190) -173 + j*(177) -170 + j*(-153) --148 + j*(-142) --109 + j*(144) -128 + j*(57) --21 + j*(-135) --193 + j*(74) -42 + j*(246) -203 + j*(37) -45 + j*(-69) -21 + j*(54) -144 + j*(16) -93 + j*(-97) -38 + j*(-51) -118 + j*(-80) -45 + j*(-235) --166 + j*(-204) --220 + j*(-24) --149 + j*(75) --78 + j*(117) -16 + j*(105) -23 + j*(11) --76 + j*(37) --7 + j*(185) -194 + j*(125) -190 + j*(-84) -45 + j*(-119) -28 + j*(-83) --14 + j*(-139) --162 + j*(-71) --115 + j*(148) -133 + j*(147) -187 + j*(-83) -16 + j*(-179) --76 + j*(-82) --33 + j*(-36) --30 + j*(-78) --91 + j*(-79) --127 + j*(-24) --125 + j*(30) --112 + j*(84) --52 + j*(161) -103 + j*(162) -213 + j*(-22) -71 + j*(-232) --186 + j*(-186) --230 + j*(35) --110 + j*(97) --126 + j*(50) --202 + j*(181) --38 + j*(369) -234 + j*(290) -279 + j*(59) -192 + j*(-30) -180 + j*(-76) -80 + j*(-197) --156 + j*(-118) --127 + j*(197) -230 + j*(240) -357 + j*(-110) -89 + j*(-301) --90 + j*(-158) --49 + j*(-65) --64 + j*(-64) --56 + j*(29) -84 + j*(9) -41 + j*(-170) --170 + j*(-97) --65 + j*(140) -202 + j*(-10) -26 + j*(-335) --357 + j*(-192) --310 + j*(196) --2 + j*(245) -78 + j*(64) -8 + j*(8) --12 + j*(19) --44 + j*(29) --33 + j*(104) -85 + j*(107) -105 + j*(-25) --24 + j*(-45) --27 + j*(93) -144 + j*(96) -188 + j*(-94) -28 + j*(-198) --100 + j*(-114) --93 + j*(-23) --74 + j*(-4) --90 + j*(39) --28 + j*(117) -111 + j*(85) -137 + j*(-92) --47 + j*(-187) --205 + j*(-25) --78 + j*(178) -155 + j*(92) -112 + j*(-166) --160 + j*(-181) --235 + j*(68) --44 + j*(175) -44 + j*(33) --103 + j*(-21) --174 + j*(165) -8 + j*(320) -242 + j*(232) -292 + j*(9) -166 + j*(-132) -25 + j*(-111) --6 + j*(-17) -49 + j*(25) -98 + j*(0) -110 + j*(-52) -78 + j*(-95) -43 + j*(-95) -57 + j*(-105) -17 + j*(-192) --161 + j*(-177) --211 + j*(55) -24 + j*(159) -147 + j*(-49) --27 + j*(-159) --86 + j*(-21) -30 + j*(-39) --74 + j*(-160) --217 + j*(10) -6 + j*(170) -178 + j*(-110) --146 + j*(-326) --436 + j*(-13) --206 + j*(317) -84 + j*(190) --2 + j*(-10) --135 + j*(107) -26 + j*(238) -175 + j*(51) --33 + j*(-112) --230 + j*(151) -72 + j*(428) -441 + j*(163) -285 + j*(-211) -31 + j*(-141) -122 + j*(-71) -59 + j*(-276) --257 + j*(-174) --159 + j*(170) -137 + j*(47) --65 + j*(-188) --270 + j*(93) -35 + j*(292) -190 + j*(24) --17 + j*(-28) -60 + j*(139) -204 + j*(-42) --46 + j*(-151) --100 + j*(155) -249 + j*(170) -259 + j*(-165) -19 + j*(-155) -119 + j*(-50) -136 + j*(-286) --193 + j*(-291) --197 + j*(45) -93 + j*(-6) --42 + j*(-261) --276 + j*(-72) --58 + j*(115) -63 + j*(-158) --290 + j*(-265) --474 + j*(115) --182 + j*(390) -96 + j*(258) -81 + j*(59) --41 + j*(51) --43 + j*(172) -125 + j*(212) -248 + j*(37) -133 + j*(-148) --28 + j*(-124) --58 + j*(-66) --134 + j*(-73) --265 + j*(95) --115 + j*(383) -272 + j*(359) -402 + j*(-1) -164 + j*(-211) --20 + j*(-98) -35 + j*(7) -76 + j*(-46) -15 + j*(-50) -42 + j*(10) -103 + j*(-47) -29 + j*(-105) -1 + j*(-14) -133 + j*(-28) -109 + j*(-211) --85 + j*(-211) --73 + j*(-80) --12 + j*(-185) --257 + j*(-252) --415 + j*(74) --114 + j*(316) -127 + j*(92) --46 + j*(-83) --161 + j*(90) -21 + j*(185) -119 + j*(18) --19 + j*(-86) --134 + j*(21) --71 + j*(149) -52 + j*(132) -54 + j*(53) -23 + j*(91) -148 + j*(122) -232 + j*(-80) -6 + j*(-236) --189 + j*(-35) --30 + j*(151) -110 + j*(29) -18 + j*(-44) -18 + j*(25) -71 + j*(-54) --92 + j*(-98) --150 + j*(140) -132 + j*(248) -313 + j*(-16) -139 + j*(-256) --113 + j*(-218) --223 + j*(-1) --79 + j*(244) -271 + j*(206) -365 + j*(-177) -55 + j*(-370) --127 + j*(-204) --74 + j*(-156) --203 + j*(-210) --339 + j*(19) --121 + j*(228) -83 + j*(73) --7 + j*(-76) --74 + j*(-42) --105 + j*(-87) --296 + j*(-25) --277 + j*(303) -100 + j*(375) -226 + j*(42) --40 + j*(-61) --86 + j*(187) -175 + j*(223) -258 + j*(-19) -107 + j*(-147) --11 + j*(-129) --97 + j*(-93) --180 + j*(18) --139 + j*(190) -23 + j*(274) -184 + j*(236) -315 + j*(129) -383 + j*(-73) -267 + j*(-321) --45 + j*(-396) --294 + j*(-148) --168 + j*(194) -203 + j*(185) -301 + j*(-173) --1 + j*(-367) --240 + j*(-165) --136 + j*(38) -1 + j*(-26) --81 + j*(-139) --235 + j*(-66) --253 + j*(145) --54 + j*(307) -235 + j*(204) -265 + j*(-140) --65 + j*(-286) --284 + j*(-6) --80 + j*(246) -168 + j*(127) -129 + j*(-69) -18 + j*(-79) -10 + j*(-55) --6 + j*(-84) --62 + j*(-88) --127 + j*(-64) --195 + j*(52) --80 + j*(241) -212 + j*(180) -235 + j*(-160) --88 + j*(-255) --211 + j*(1) --27 + j*(86) --21 + j*(-64) --187 + j*(-4) --112 + j*(192) -86 + j*(136) -46 + j*(-40) --119 + j*(-14) --132 + j*(142) --19 + j*(224) -86 + j*(201) -132 + j*(159) -184 + j*(144) -286 + j*(71) -287 + j*(-121) -101 + j*(-206) -8 + j*(-66) -159 + j*(-26) -183 + j*(-241) --70 + j*(-322) --205 + j*(-115) --80 + j*(1) --47 + j*(-96) --193 + j*(-70) --182 + j*(145) -61 + j*(205) -191 + j*(-12) -30 + j*(-181) --134 + j*(-75) --66 + j*(42) --21 + j*(-38) --177 + j*(-21) --162 + j*(250) -190 + j*(324) -389 + j*(-1) -202 + j*(-268) --9 + j*(-250) --85 + j*(-190) --165 + j*(-132) --175 + j*(-1) --69 + j*(38) --55 + j*(-35) --124 + j*(-18) --110 + j*(44) --94 + j*(37) --130 + j*(83) --62 + j*(179) -81 + j*(139) -98 + j*(-9) --30 + j*(-78) --156 + j*(11) --132 + j*(190) -69 + j*(250) -196 + j*(72) -58 + j*(-65) --54 + j*(53) -72 + j*(150) -165 + j*(21) -50 + j*(-70) --45 + j*(34) -35 + j*(168) -235 + j*(170) -391 + j*(-54) -242 + j*(-366) --132 + j*(-349) --209 + j*(-13) -61 + j*(66) -103 + j*(-178) --140 + j*(-204) --170 + j*(10) --18 + j*(20) --69 + j*(-89) --191 + j*(18) --77 + j*(186) -122 + j*(123) -134 + j*(-72) --21 + j*(-153) --157 + j*(-62) --147 + j*(90) --30 + j*(162) -78 + j*(128) -128 + j*(52) -129 + j*(-39) -54 + j*(-112) --57 + j*(-70) --37 + j*(69) -148 + j*(86) -257 + j*(-141) -59 + j*(-385) --279 + j*(-310) --349 + j*(4) --136 + j*(132) --54 + j*(-13) --226 + j*(-44) --296 + j*(187) --86 + j*(364) -149 + j*(270) -174 + j*(87) -90 + j*(40) -105 + j*(76) -181 + j*(-5) -86 + j*(-147) --91 + j*(-65) --9 + j*(110) -159 + j*(-8) --11 + j*(-176) --190 + j*(42) -68 + j*(233) -261 + j*(-37) -21 + j*(-206) --69 + j*(-16) -96 + j*(-71) --120 + j*(-277) --433 + j*(43) --113 + j*(453) -306 + j*(214) -134 + j*(-105) --35 + j*(83) -228 + j*(158) -294 + j*(-152) -21 + j*(-230) --8 + j*(-52) -100 + j*(-127) --74 + j*(-223) --178 + j*(4) -83 + j*(98) -169 + j*(-205) --161 + j*(-320) --317 + j*(-17) --81 + j*(132) -8 + j*(-56) --179 + j*(-90) --199 + j*(103) --43 + j*(113) --83 + j*(4) --197 + j*(112) --80 + j*(269) -73 + j*(223) -95 + j*(174) -190 + j*(176) -292 + j*(6) -148 + j*(-172) --16 + j*(-81) -67 + j*(17) -118 + j*(-107) --34 + j*(-157) --94 + j*(-16) -16 + j*(43) -71 + j*(-37) -34 + j*(-95) --16 + j*(-122) --96 + j*(-127) --170 + j*(-51) --168 + j*(58) --98 + j*(134) -1 + j*(136) -44 + j*(64) --2 + j*(47) -29 + j*(110) -141 + j*(53) -81 + j*(-95) --76 + j*(-31) -3 + j*(137) -197 + j*(63) -176 + j*(-136) -30 + j*(-194) --62 + j*(-160) --128 + j*(-101) --132 + j*(-6) --75 + j*(22) --81 + j*(8) --88 + j*(57) --30 + j*(64) --62 + j*(31) --95 + j*(136) -72 + j*(214) -193 + j*(50) -74 + j*(-64) -23 + j*(25) -122 + j*(24) -123 + j*(-87) -58 + j*(-127) -1 + j*(-174) --169 + j*(-155) --218 + j*(85) -28 + j*(179) -113 + j*(-44) --93 + j*(-81) --86 + j*(119) -101 + j*(91) -65 + j*(-50) -4 + j*(-4) -80 + j*(-27) --8 + j*(-143) --153 + j*(-26) --38 + j*(117) -76 + j*(17) --6 + j*(-52) --33 + j*(6) --18 + j*(-1) --59 + j*(51) -66 + j*(141) -221 + j*(-31) -57 + j*(-251) --185 + j*(-149) --173 + j*(52) --64 + j*(115) -47 + j*(105) -112 + j*(-37) --73 + j*(-145) --216 + j*(90) -59 + j*(261) -247 + j*(-18) --3 + j*(-190) --117 + j*(4) -4 + j*(30) --83 + j*(-12) --57 + j*(210) -305 + j*(148) -264 + j*(-318) --233 + j*(-344) --327 + j*(86) --46 + j*(213) -59 + j*(112) -123 + j*(61) -132 + j*(-136) --174 + j*(-194) --283 + j*(185) -114 + j*(347) -311 + j*(16) -122 + j*(-151) -63 + j*(-121) --25 + j*(-228) --282 + j*(-91) --136 + j*(250) -212 + j*(86) --5 + j*(-243) --327 + j*(39) --32 + j*(371) -282 + j*(131) -129 + j*(-94) -45 + j*(4) -151 + j*(-32) -63 + j*(-173) --78 + j*(-105) --53 + j*(-16) --42 + j*(-6) --19 + j*(64) -116 + j*(46) -123 + j*(-122) --24 + j*(-168) --87 + j*(-91) --96 + j*(-54) --105 + j*(11) --15 + j*(45) -6 + j*(-69) --151 + j*(-69) --148 + j*(140) -89 + j*(154) -129 + j*(-83) --83 + j*(-156) --197 + j*(5) --127 + j*(157) -31 + j*(202) -190 + j*(87) -156 + j*(-146) --85 + j*(-204) --216 + j*(-30) --155 + j*(107) --95 + j*(154) --13 + j*(214) -136 + j*(175) -153 + j*(21) -40 + j*(-1) -65 + j*(89) -175 + j*(22) -105 + j*(-119) --43 + j*(-61) -13 + j*(91) -191 + j*(42) -188 + j*(-163) -1 + j*(-242) --140 + j*(-134) --145 + j*(11) --46 + j*(112) -123 + j*(88) -182 + j*(-113) --4 + j*(-250) --164 + j*(-119) --84 + j*(-23) --111 + j*(-127) --332 + j*(-11) --223 + j*(346) -188 + j*(330) -250 + j*(-14) -39 + j*(-63) -91 + j*(49) -187 + j*(-119) --20 + j*(-245) --148 + j*(-88) --70 + j*(-34) --145 + j*(-76) --208 + j*(101) -6 + j*(201) -101 + j*(0) --80 + j*(-46) --74 + j*(122) -69 + j*(79) --21 + j*(-8) --45 + j*(161) -223 + j*(167) -260 + j*(-165) --73 + j*(-249) --171 + j*(35) -70 + j*(114) -132 + j*(-117) --102 + j*(-209) --268 + j*(-11) --166 + j*(224) -73 + j*(252) -189 + j*(76) -90 + j*(-40) -28 + j*(37) -148 + j*(68) -208 + j*(-92) -79 + j*(-209) --41 + j*(-173) --88 + j*(-124) --132 + j*(-63) --104 + j*(26) --31 + j*(5) --103 + j*(-40) --168 + j*(113) -37 + j*(241) -228 + j*(40) -66 + j*(-176) --133 + j*(-46) --21 + j*(117) -107 + j*(22) -41 + j*(-64) -28 + j*(-28) -63 + j*(-115) --113 + j*(-202) --288 + j*(13) --102 + j*(262) -165 + j*(146) -112 + j*(-84) --59 + j*(-62) --39 + j*(65) -69 + j*(44) -68 + j*(-50) --1 + j*(-81) --45 + j*(-60) --72 + j*(-40) --107 + j*(0) --97 + j*(94) -23 + j*(130) -104 + j*(6) --19 + j*(-107) --163 + j*(2) --98 + j*(163) -32 + j*(159) -57 + j*(105) -67 + j*(107) -103 + j*(98) -129 + j*(96) -221 + j*(78) -284 + j*(-74) -160 + j*(-206) -58 + j*(-151) -107 + j*(-152) -34 + j*(-272) --140 + j*(-206) --98 + j*(-59) --9 + j*(-129) --130 + j*(-213) --245 + j*(-123) --288 + j*(-35) --350 + j*(134) --155 + j*(395) -218 + j*(272) -158 + j*(-80) --105 + j*(11) -93 + j*(211) -281 + j*(-88) --50 + j*(-284) --209 + j*(13) -38 + j*(69) --41 + j*(-163) --296 + j*(27) --74 + j*(295) -156 + j*(88) --33 + j*(-39) --42 + j*(158) -167 + j*(74) -14 + j*(-136) --183 + j*(77) -65 + j*(263) -221 + j*(14) --19 + j*(-74) --25 + j*(204) -338 + j*(187) -400 + j*(-231) -31 + j*(-421) --223 + j*(-202) --164 + j*(-1) --90 + j*(11) --108 + j*(50) --28 + j*(141) -110 + j*(79) -81 + j*(-49) -1 + j*(-29) -44 + j*(-4) -22 + j*(-83) --86 + j*(-19) -19 + j*(105) -155 + j*(-39) --16 + j*(-174) --126 + j*(8) -58 + j*(71) -61 + j*(-107) --94 + j*(-41) -53 + j*(81) -152 + j*(-152) --134 + j*(-249) --212 + j*(27) -13 + j*(31) --108 + j*(-165) --331 + j*(65) --63 + j*(331) -197 + j*(100) -23 + j*(-91) --70 + j*(56) -72 + j*(66) -44 + j*(-62) --47 + j*(-30) --16 + j*(-4) --71 + j*(-36) --115 + j*(84) -42 + j*(141) -95 + j*(-24) --60 + j*(-59) --73 + j*(71) -12 + j*(56) --54 + j*(25) --49 + j*(161) -138 + j*(169) -171 + j*(-16) -31 + j*(-37) -76 + j*(78) -231 + j*(-36) -105 + j*(-274) --192 + j*(-209) --205 + j*(77) -11 + j*(123) -16 + j*(-23) --105 + j*(62) -64 + j*(218) -275 + j*(9) -74 + j*(-238) --168 + j*(-60) --8 + j*(139) -133 + j*(-11) --16 + j*(-84) --25 + j*(78) -161 + j*(52) -138 + j*(-136) --6 + j*(-127) -21 + j*(-45) -83 + j*(-111) -18 + j*(-208) --103 + j*(-223) --221 + j*(-151) --252 + j*(-1) --166 + j*(93) --98 + j*(93) --58 + j*(98) --4 + j*(57) --63 + j*(-6) --138 + j*(103) -16 + j*(211) -146 + j*(52) -10 + j*(-53) --27 + j*(73) -110 + j*(28) --1 + j*(-129) --175 + j*(21) --14 + j*(196) -130 + j*(52) -11 + j*(-21) -27 + j*(103) -193 + j*(16) -107 + j*(-202) --131 + j*(-188) --225 + j*(0) --151 + j*(190) -72 + j*(253) -236 + j*(65) -118 + j*(-120) -0 + j*(-57) -58 + j*(-48) --39 + j*(-142) --183 + j*(23) -5 + j*(203) -180 + j*(36) -63 + j*(-68) -97 + j*(18) -214 + j*(-175) --72 + j*(-381) --351 + j*(-119) --185 + j*(129) --79 + j*(41) --179 + j*(95) --40 + j*(252) -127 + j*(124) -24 + j*(40) -58 + j*(175) -269 + j*(78) -195 + j*(-171) -1 + j*(-156) --3 + j*(-79) --44 + j*(-112) --129 + j*(-7) --21 + j*(110) -84 + j*(32) -48 + j*(-4) -119 + j*(15) -174 + j*(-157) --36 + j*(-284) --210 + j*(-117) --117 + j*(38) --27 + j*(-5) --57 + j*(-45) --81 + j*(-31) --107 + j*(-19) --129 + j*(36) --92 + j*(88) --56 + j*(98) --28 + j*(129) -60 + j*(140) -129 + j*(58) -108 + j*(-37) -47 + j*(-77) --11 + j*(-66) --13 + j*(-17) -44 + j*(-52) --26 + j*(-168) --223 + j*(-115) --238 + j*(111) --64 + j*(192) -21 + j*(105) --16 + j*(61) --45 + j*(96) --6 + j*(173) -145 + j*(181) -225 + j*(-13) -28 + j*(-133) --81 + j*(72) -163 + j*(156) -250 + j*(-125) --13 + j*(-226) --88 + j*(-43) -2 + j*(-64) --158 + j*(-110) --231 + j*(163) -66 + j*(300) -243 + j*(77) -145 + j*(-66) -91 + j*(-82) --3 + j*(-118) --97 + j*(46) -150 + j*(188) -357 + j*(-127) -28 + j*(-403) --263 + j*(-116) --34 + j*(139) -162 + j*(-49) -13 + j*(-190) --71 + j*(-94) --10 + j*(-69) --17 + j*(-113) --30 + j*(-117) --39 + j*(-168) --137 + j*(-205) --234 + j*(-144) --278 + j*(-71) --324 + j*(36) --268 + j*(194) --107 + j*(233) --40 + j*(147) -144 + j*(100) -114 + j*(-139) --59 + j*(-81) -41 + j*(-2) -23 + j*(-161) --189 + j*(-74) --52 + j*(148) -144 + j*(-46) --123 + j*(-207) --264 + j*(122) -91 + j*(254) -206 + j*(-91) --107 + j*(-187) --196 + j*(83) -6 + j*(176) -105 + j*(62) -81 + j*(-24) -15 + j*(-57) --35 + j*(6) -52 + j*(47) -86 + j*(-85) --80 + j*(-120) --107 + j*(52) -46 + j*(39) --36 + j*(-94) --171 + j*(52) -12 + j*(190) -124 + j*(6) --62 + j*(-54) --77 + j*(151) -130 + j*(168) -180 + j*(26) -166 + j*(-25) -178 + j*(-141) --4 + j*(-233) --127 + j*(-46) -69 + j*(38) -97 + j*(-207) --206 + j*(-209) --213 + j*(114) -80 + j*(118) -58 + j*(-122) --129 + j*(-64) --42 + j*(75) -59 + j*(-29) --37 + j*(-95) --54 + j*(-34) --23 + j*(-101) --174 + j*(-157) --306 + j*(5) --240 + j*(180) --135 + j*(243) --26 + j*(291) -132 + j*(257) -208 + j*(124) -208 + j*(8) -157 + j*(-139) --93 + j*(-210) --298 + j*(95) -19 + j*(426) -450 + j*(151) -264 + j*(-317) --165 + j*(-221) --127 + j*(117) -110 + j*(104) -114 + j*(-34) -76 + j*(-50) -64 + j*(-108) --61 + j*(-112) --74 + j*(44) -88 + j*(50) -76 + j*(-103) --59 + j*(-65) -11 + j*(50) -115 + j*(-42) -33 + j*(-141) --35 + j*(-100) --25 + j*(-98) --86 + j*(-113) --129 + j*(-36) --80 + j*(10) --71 + j*(-4) --76 + j*(33) --16 + j*(42) --2 + j*(-22) --56 + j*(-44) --93 + j*(-27) --144 + j*(9) --151 + j*(122) --30 + j*(186) -37 + j*(105) --25 + j*(115) -68 + j*(235) -293 + j*(144) -298 + j*(-127) -99 + j*(-245) --52 + j*(-191) --116 + j*(-89) --85 + j*(19) -25 + j*(21) -33 + j*(-80) --43 + j*(-100) --53 + j*(-90) --119 + j*(-156) --303 + j*(-93) --355 + j*(148) --214 + j*(329) --27 + j*(395) -199 + j*(349) -314 + j*(112) -151 + j*(-49) -52 + j*(86) -244 + j*(121) -284 + j*(-127) -49 + j*(-185) -27 + j*(2) -211 + j*(-42) -151 + j*(-265) --82 + j*(-264) --145 + j*(-88) --41 + j*(-4) -49 + j*(-73) --9 + j*(-200) --190 + j*(-180) --232 + j*(2) --119 + j*(68) --112 + j*(33) --122 + j*(126) -45 + j*(161) -108 + j*(-21) --56 + j*(-84) --106 + j*(52) --6 + j*(88) -16 + j*(47) -35 + j*(50) -67 + j*(-11) --2 + j*(-44) -1 + j*(21) -67 + j*(-56) --99 + j*(-135) --204 + j*(109) -81 + j*(243) -216 + j*(-44) --47 + j*(-130) --43 + j*(114) -233 + j*(11) -84 + j*(-315) --265 + j*(-170) --150 + j*(167) -147 + j*(76) -84 + j*(-208) --208 + j*(-217) --339 + j*(59) --137 + j*(312) -177 + j*(216) -168 + j*(-83) --66 + j*(-107) --75 + j*(45) --13 + j*(2) --144 + j*(21) --92 + j*(252) -191 + j*(226) -193 + j*(-28) -28 + j*(-5) -127 + j*(87) -182 + j*(-74) -2 + j*(-99) -33 + j*(83) -234 + j*(-5) -139 + j*(-223) --50 + j*(-148) -25 + j*(-31) -87 + j*(-139) --49 + j*(-194) --114 + j*(-74) --28 + j*(-21) -13 + j*(-83) --19 + j*(-139) --81 + j*(-182) --221 + j*(-189) --378 + j*(-21) --302 + j*(275) -32 + j*(345) -192 + j*(62) --36 + j*(-93) --155 + j*(137) -107 + j*(244) -225 + j*(-13) -21 + j*(-123) --39 + j*(11) -32 + j*(-8) --66 + j*(-26) --44 + j*(143) -177 + j*(104) -151 + j*(-119) --4 + j*(-110) -28 + j*(-82) --83 + j*(-192) --298 + j*(13) --53 + j*(310) -272 + j*(63) -35 + j*(-238) --210 + j*(-17) --16 + j*(141) -29 + j*(-34) --162 + j*(33) --40 + j*(267) -216 + j*(182) -217 + j*(-12) -163 + j*(-77) -107 + j*(-164) --49 + j*(-154) --57 + j*(-6) -54 + j*(-30) --21 + j*(-124) --98 + j*(-25) --4 + j*(8) --48 + j*(-83) --159 + j*(32) --23 + j*(166) -86 + j*(62) -21 + j*(54) -163 + j*(147) -370 + j*(-109) -130 + j*(-465) --307 + j*(-383) --434 + j*(-24) --293 + j*(241) --41 + j*(349) -219 + j*(228) -253 + j*(-38) -90 + j*(-149) -0 + j*(-105) --21 + j*(-91) --54 + j*(-76) --62 + j*(-71) --137 + j*(-81) --226 + j*(62) --79 + j*(230) -105 + j*(127) -32 + j*(-2) --16 + j*(91) -112 + j*(83) -72 + j*(-52) --34 + j*(34) -112 + j*(119) -197 + j*(-66) -29 + j*(-139) -23 + j*(-28) -93 + j*(-136) --129 + j*(-206) --209 + j*(88) -128 + j*(161) -176 + j*(-214) --231 + j*(-250) --276 + j*(163) -103 + j*(216) -162 + j*(-110) --103 + j*(-170) --168 + j*(8) --94 + j*(54) --115 + j*(67) --83 + j*(164) -49 + j*(171) -99 + j*(70) -49 + j*(5) --25 + j*(11) --71 + j*(113) -41 + j*(254) -279 + j*(206) -356 + j*(-46) -205 + j*(-207) -76 + j*(-194) -20 + j*(-175) --49 + j*(-140) --44 + j*(-54) -33 + j*(-76) --28 + j*(-177) --183 + j*(-119) --182 + j*(59) --43 + j*(129) -66 + j*(73) -86 + j*(-34) -5 + j*(-106) --82 + j*(-42) --15 + j*(33) -47 + j*(-59) --76 + j*(-122) --139 + j*(6) --29 + j*(49) --35 + j*(-45) --131 + j*(8) --66 + j*(96) --30 + j*(40) --101 + j*(95) -33 + j*(218) -203 + j*(63) -78 + j*(-99) -5 + j*(-5) -102 + j*(-70) --103 + j*(-209) --305 + j*(100) -66 + j*(353) -339 + j*(-42) --57 + j*(-307) --301 + j*(69) -21 + j*(284) -190 + j*(57) -82 + j*(-44) -60 + j*(-49) --45 + j*(-98) --144 + j*(104) -140 + j*(253) -336 + j*(-73) -31 + j*(-284) --132 + j*(-40) -67 + j*(16) -7 + j*(-181) --216 + j*(-55) --95 + j*(177) -87 + j*(103) -58 + j*(34) -124 + j*(73) -238 + j*(-86) -78 + j*(-296) --180 + j*(-224) --221 + j*(8) --57 + j*(126) -105 + j*(9) --1 + j*(-199) --282 + j*(-111) --247 + j*(228) -83 + j*(258) -134 + j*(0) --55 + j*(-5) -2 + j*(168) -202 + j*(102) -206 + j*(-102) -62 + j*(-202) --98 + j*(-160) --134 + j*(5) -27 + j*(59) -62 + j*(-136) --194 + j*(-168) --259 + j*(117) --12 + j*(205) -42 + j*(38) --71 + j*(74) -40 + j*(184) -169 + j*(58) -74 + j*(-47) -27 + j*(14) -86 + j*(18) -86 + j*(-35) -77 + j*(-62) -31 + j*(-113) --66 + j*(-48) -53 + j*(76) -242 + j*(-124) --1 + j*(-432) --417 + j*(-264) --421 + j*(142) --186 + j*(296) --6 + j*(315) -218 + j*(226) -247 + j*(-93) --90 + j*(-182) --182 + j*(164) -179 + j*(245) -259 + j*(-111) --62 + j*(-174) --81 + j*(103) -185 + j*(71) -134 + j*(-216) --175 + j*(-194) --214 + j*(105) -35 + j*(205) -169 + j*(27) -64 + j*(-98) --13 + j*(-45) -30 + j*(-47) --57 + j*(-122) --204 + j*(22) --45 + j*(244) -211 + j*(115) -117 + j*(-112) --33 + j*(-10) -135 + j*(69) -196 + j*(-180) --95 + j*(-271) --214 + j*(4) -13 + j*(116) -98 + j*(-71) --56 + j*(-140) --122 + j*(-34) --77 + j*(11) --88 + j*(7) --112 + j*(77) --31 + j*(173) -130 + j*(153) -206 + j*(-4) -139 + j*(-139) -52 + j*(-182) --37 + j*(-235) --233 + j*(-211) --333 + j*(33) --136 + j*(209) -6 + j*(76) --130 + j*(20) --127 + j*(216) -112 + j*(206) -97 + j*(-23) --114 + j*(33) --18 + j*(248) -208 + j*(163) -162 + j*(-18) -74 + j*(20) -156 + j*(33) -157 + j*(-88) -54 + j*(-106) -54 + j*(-64) -59 + j*(-120) --37 + j*(-133) --66 + j*(-51) --35 + j*(-43) --90 + j*(-32) --62 + j*(88) -112 + j*(53) -64 + j*(-175) --239 + j*(-116) --204 + j*(276) -263 + j*(312) -400 + j*(-181) --59 + j*(-414) --345 + j*(-23) --17 + j*(279) -287 + j*(-2) -54 + j*(-317) --267 + j*(-153) --187 + j*(132) -25 + j*(112) -10 + j*(-30) --101 + j*(14) --50 + j*(140) -96 + j*(128) -144 + j*(-4) -58 + j*(-91) --30 + j*(-45) --2 + j*(36) -90 + j*(21) -115 + j*(-74) -66 + j*(-150) --4 + j*(-198) --127 + j*(-223) --272 + j*(-129) --288 + j*(60) --172 + j*(156) --106 + j*(139) --111 + j*(180) --2 + j*(269) -180 + j*(195) -193 + j*(-4) -47 + j*(-75) --20 + j*(1) -14 + j*(30) --6 + j*(3) --56 + j*(64) -12 + j*(162) -153 + j*(139) -195 + j*(6) -124 + j*(-74) -64 + j*(-59) -65 + j*(-44) -59 + j*(-62) -30 + j*(-60) -30 + j*(-37) -40 + j*(-38) -44 + j*(-30) -95 + j*(-29) -142 + j*(-123) -58 + j*(-236) --76 + j*(-217) --99 + j*(-147) --112 + j*(-163) --206 + j*(-144) --247 + j*(-40) --233 + j*(20) --268 + j*(112) --160 + j*(294) -119 + j*(248) -119 + j*(-46) --166 + j*(-35) --129 + j*(279) -225 + j*(253) -252 + j*(-98) --35 + j*(-184) --156 + j*(-9) --127 + j*(107) --74 + j*(223) -131 + j*(286) -298 + j*(88) -164 + j*(-94) -57 + j*(7) -195 + j*(31) -187 + j*(-161) --21 + j*(-151) -23 + j*(42) -228 + j*(-50) -130 + j*(-291) --111 + j*(-240) --89 + j*(-58) -41 + j*(-115) --55 + j*(-274) --294 + j*(-221) --366 + j*(43) --172 + j*(231) -43 + j*(133) --14 + j*(-48) --181 + j*(25) --89 + j*(216) -122 + j*(141) -79 + j*(-52) --66 + j*(-21) --28 + j*(63) --8 + j*(-1) --116 + j*(37) --42 + j*(202) -159 + j*(124) -83 + j*(-76) --100 + j*(16) -22 + j*(194) -196 + j*(66) -77 + j*(-83) --19 + j*(47) -152 + j*(118) -251 + j*(-88) -80 + j*(-239) --86 + j*(-166) --109 + j*(-57) --93 + j*(1) --73 + j*(54) --21 + j*(100) -72 + j*(111) -172 + j*(20) -124 + j*(-136) --50 + j*(-129) --43 + j*(38) -132 + j*(0) -69 + j*(-211) --181 + j*(-151) --145 + j*(109) -105 + j*(105) -136 + j*(-108) --2 + j*(-182) --82 + j*(-158) --173 + j*(-144) --274 + j*(-18) --214 + j*(171) --36 + j*(211) -54 + j*(119) -42 + j*(52) -20 + j*(42) -28 + j*(47) -45 + j*(26) -29 + j*(4) -18 + j*(19) -47 + j*(9) -21 + j*(-30) --14 + j*(29) -117 + j*(64) -194 + j*(-156) --80 + j*(-331) --351 + j*(-86) --207 + j*(208) -8 + j*(154) --31 + j*(71) --18 + j*(165) -136 + j*(132) -124 + j*(-31) -2 + j*(-37) --8 + j*(30) -4 + j*(45) -24 + j*(95) -135 + j*(85) -139 + j*(-47) -35 + j*(-35) -120 + j*(34) -194 + j*(-156) --86 + j*(-270) --250 + j*(62) -107 + j*(274) -376 + j*(-83) -81 + j*(-404) --240 + j*(-239) --210 + j*(-13) --152 + j*(24) --155 + j*(121) -13 + j*(231) -222 + j*(92) -180 + j*(-144) -1 + j*(-199) --95 + j*(-138) --144 + j*(-87) --191 + j*(10) --120 + j*(147) -57 + j*(143) -117 + j*(-29) --23 + j*(-131) --144 + j*(-45) --124 + j*(57) --93 + j*(82) --83 + j*(140) -27 + j*(192) -135 + j*(89) -48 + j*(-26) --49 + j*(83) -102 + j*(208) -302 + j*(53) -222 + j*(-209) --25 + j*(-246) --151 + j*(-85) --100 + j*(69) -42 + j*(111) -156 + j*(-3) -81 + j*(-167) --112 + j*(-141) --125 + j*(42) -30 + j*(71) -41 + j*(-50) --55 + j*(-14) -54 + j*(79) -187 + j*(-110) --51 + j*(-331) --372 + j*(-107) --217 + j*(260) -122 + j*(160) -20 + j*(-132) --268 + j*(17) --103 + j*(351) -269 + j*(233) -226 + j*(-110) --33 + j*(-105) --6 + j*(63) -107 + j*(-15) --10 + j*(-103) --88 + j*(27) -31 + j*(91) -69 + j*(8) -44 + j*(25) -150 + j*(0) -107 + j*(-216) --198 + j*(-200) --223 + j*(147) -117 + j*(201) -166 + j*(-112) --123 + j*(-139) --135 + j*(134) -117 + j*(157) -165 + j*(-52) -25 + j*(-124) --57 + j*(-50) --33 + j*(39) -78 + j*(47) -110 + j*(-95) --59 + j*(-139) --91 + j*(61) -158 + j*(62) -148 + j*(-249) --190 + j*(-263) --224 + j*(35) --13 + j*(33) --105 + j*(-115) --235 + j*(47) --71 + j*(166) --21 + j*(40) --129 + j*(108) -42 + j*(244) -213 + j*(25) --16 + j*(-142) --153 + j*(88) -67 + j*(202) -175 + j*(26) -91 + j*(-64) -47 + j*(-93) --87 + j*(-119) --182 + j*(95) -90 + j*(248) -279 + j*(-56) --25 + j*(-264) --223 + j*(11) --1 + j*(165) -72 + j*(1) --47 + j*(19) -42 + j*(117) -108 + j*(-4) --17 + j*(0) -78 + j*(148) -271 + j*(-11) -112 + j*(-221) --30 + j*(-89) -124 + j*(-91) --13 + j*(-344) --397 + j*(-146) --210 + j*(320) -266 + j*(155) -98 + j*(-298) --337 + j*(-121) --184 + j*(305) -194 + j*(218) -178 + j*(-49) -65 + j*(-50) -132 + j*(-78) -56 + j*(-267) --237 + j*(-258) --377 + j*(42) --192 + j*(322) -141 + j*(327) -325 + j*(55) -189 + j*(-217) --54 + j*(-221) --131 + j*(-95) --144 + j*(-40) --175 + j*(66) --47 + j*(191) -121 + j*(77) -18 + j*(-81) --108 + j*(42) -54 + j*(137) -127 + j*(-64) --112 + j*(-124) --172 + j*(144) -100 + j*(218) -187 + j*(-15) -14 + j*(-90) --21 + j*(30) -62 + j*(21) -18 + j*(-42) --34 + j*(35) -68 + j*(101) -170 + j*(2) -119 + j*(-130) -6 + j*(-136) --16 + j*(-76) -10 + j*(-100) --74 + j*(-148) --179 + j*(-42) --91 + j*(98) -42 + j*(25) --37 + j*(-88) --147 + j*(-1) --86 + j*(103) --18 + j*(102) -36 + j*(106) -126 + j*(17) -11 + j*(-145) --206 + j*(-6) --47 + j*(245) -207 + j*(66) --15 + j*(-161) --214 + j*(128) -122 + j*(326) -318 + j*(7) -70 + j*(-118) -91 + j*(78) -311 + j*(-99) -57 + j*(-383) --241 + j*(-135) --14 + j*(94) -115 + j*(-156) --186 + j*(-227) --252 + j*(89) -21 + j*(159) -73 + j*(-37) --58 + j*(-59) --62 + j*(23) --24 + j*(32) -8 + j*(34) -42 + j*(-37) --79 + j*(-105) --193 + j*(67) -2 + j*(228) -190 + j*(57) -70 + j*(-106) --11 + j*(-27) -69 + j*(-54) --45 + j*(-185) --231 + j*(-43) --115 + j*(156) -37 + j*(57) --93 + j*(-25) --156 + j*(170) -78 + j*(279) -248 + j*(86) -146 + j*(-98) -6 + j*(-70) -16 + j*(18) -95 + j*(-5) -75 + j*(-119) --78 + j*(-141) --161 + j*(25) --20 + j*(162) -144 + j*(63) -93 + j*(-98) --44 + j*(-76) --37 + j*(32) -53 + j*(35) -81 + j*(-43) -35 + j*(-105) --49 + j*(-117) --122 + j*(-47) --89 + j*(52) --2 + j*(38) --39 + j*(-33) --122 + j*(45) --23 + j*(166) -119 + j*(76) -28 + j*(-49) --66 + j*(86) -141 + j*(190) -303 + j*(-67) -58 + j*(-293) --188 + j*(-107) --60 + j*(103) -87 + j*(5) --7 + j*(-75) --25 + j*(29) -105 + j*(-1) -59 + j*(-175) --141 + j*(-156) --177 + j*(27) --63 + j*(100) -4 + j*(71) -35 + j*(47) -62 + j*(-2) -26 + j*(-59) --28 + j*(-43) --9 + j*(-8) -21 + j*(-62) --70 + j*(-139) --241 + j*(-59) --252 + j*(199) -17 + j*(357) -298 + j*(173) -252 + j*(-141) -3 + j*(-206) --95 + j*(-69) --40 + j*(-15) --54 + j*(-54) --133 + j*(-16) --143 + j*(107) --35 + j*(205) -133 + j*(177) -202 + j*(1) -71 + j*(-123) --56 + j*(-41) -13 + j*(59) -94 + j*(-21) -19 + j*(-98) --47 + j*(-52) --40 + j*(-37) --110 + j*(-35) --149 + j*(111) -23 + j*(215) -165 + j*(74) -76 + j*(-56) --11 + j*(1) -30 + j*(45) -23 + j*(37) -51 + j*(127) -254 + j*(113) -326 + j*(-168) -64 + j*(-348) --156 + j*(-192) --112 + j*(-25) --44 + j*(-9) --15 + j*(15) -85 + j*(-18) -57 + j*(-182) --154 + j*(-184) --199 + j*(30) --31 + j*(102) -40 + j*(6) -31 + j*(-35) -49 + j*(-125) --118 + j*(-252) --381 + j*(-74) --271 + j*(275) -63 + j*(257) -85 + j*(16) --61 + j*(23) --1 + j*(112) -55 + j*(21) --43 + j*(4) --15 + j*(107) -101 + j*(37) --3 + j*(-95) --155 + j*(18) --65 + j*(187) -84 + j*(152) -90 + j*(71) -85 + j*(79) -158 + j*(64) -202 + j*(-56) -105 + j*(-194) --98 + j*(-185) --185 + j*(19) --22 + j*(162) -120 + j*(41) -18 + j*(-66) --49 + j*(47) -81 + j*(86) -91 + j*(-52) --56 + j*(-18) -25 + j*(170) -280 + j*(81) -242 + j*(-219) --45 + j*(-251) --104 + j*(-11) -115 + j*(41) -188 + j*(-203) --66 + j*(-356) --310 + j*(-163) --231 + j*(110) --1 + j*(123) -53 + j*(-40) --52 + j*(-109) --141 + j*(-64) --173 + j*(28) --115 + j*(134) -21 + j*(132) -54 + j*(7) --55 + j*(-27) --80 + j*(75) -13 + j*(101) -42 + j*(37) -21 + j*(30) -62 + j*(24) -64 + j*(-76) --80 + j*(-126) --209 + j*(16) --119 + j*(219) -111 + j*(224) -198 + j*(27) -74 + j*(-86) -3 + j*(-23) -49 + j*(-32) --34 + j*(-107) --163 + j*(16) --45 + j*(180) -108 + j*(92) -33 + j*(-2) -5 + j*(95) -135 + j*(96) -144 + j*(-18) -107 + j*(-13) -182 + j*(-74) -67 + j*(-247) --175 + j*(-125) --54 + j*(132) -190 + j*(-6) -40 + j*(-233) --161 + j*(-98) --61 + j*(39) --20 + j*(-42) --102 + j*(4) --11 + j*(105) -84 + j*(20) -41 + j*(-22) -104 + j*(-15) -120 + j*(-202) --148 + j*(-276) --279 + j*(-10) --69 + j*(116) --6 + j*(-48) --163 + j*(-61) --185 + j*(83) --119 + j*(146) --56 + j*(219) -141 + j*(226) -251 + j*(-26) -21 + j*(-221) --214 + j*(-74) --190 + j*(148) --60 + j*(253) -116 + j*(282) -306 + j*(153) -316 + j*(-95) -158 + j*(-246) --43 + j*(-279) --268 + j*(-133) --239 + j*(223) -180 + j*(308) -349 + j*(-122) --64 + j*(-347) --322 + j*(26) --8 + j*(297) -247 + j*(64) -94 + j*(-145) --49 + j*(-45) -32 + j*(45) -108 + j*(-38) -32 + j*(-130) --74 + j*(-74) --28 + j*(23) -49 + j*(-39) --59 + j*(-112) --149 + j*(50) -41 + j*(172) -185 + j*(-4) -66 + j*(-120) -44 + j*(-49) -133 + j*(-151) --36 + j*(-321) --262 + j*(-193) --228 + j*(-13) --184 + j*(-14) --239 + j*(48) --181 + j*(162) --107 + j*(170) --72 + j*(226) -110 + j*(231) -163 + j*(-16) --125 + j*(-67) --160 + j*(276) -224 + j*(334) -330 + j*(-10) -110 + j*(-105) -117 + j*(-16) -158 + j*(-151) --41 + j*(-218) --127 + j*(-69) --90 + j*(-40) --190 + j*(7) --132 + j*(233) -139 + j*(206) -105 + j*(-23) --70 + j*(91) -141 + j*(276) -378 + j*(51) -246 + j*(-183) -138 + j*(-158) -154 + j*(-242) --54 + j*(-347) --252 + j*(-144) --119 + j*(59) -10 + j*(-28) --83 + j*(-84) --122 + j*(31) --16 + j*(100) -103 + j*(54) -160 + j*(-99) -23 + j*(-279) --250 + j*(-215) --277 + j*(72) --40 + j*(152) -33 + j*(-25) --109 + j*(-80) --172 + j*(23) --148 + j*(94) --120 + j*(180) -33 + j*(251) -209 + j*(100) -108 + j*(-134) --139 + j*(-85) --134 + j*(147) -62 + j*(185) -126 + j*(57) -85 + j*(6) -94 + j*(-25) -28 + j*(-120) --146 + j*(-66) --144 + j*(151) -54 + j*(213) -146 + j*(105) -148 + j*(69) -239 + j*(5) -206 + j*(-204) --40 + j*(-253) --141 + j*(-56) --26 + j*(25) --9 + j*(-23) --25 + j*(31) -88 + j*(24) -68 + j*(-133) --115 + j*(-102) --71 + j*(83) -107 + j*(17) -22 + j*(-158) --146 + j*(-75) --86 + j*(59) --18 + j*(10) --89 + j*(6) --71 + j*(113) -38 + j*(118) -62 + j*(61) -79 + j*(71) -175 + j*(26) -182 + j*(-141) -27 + j*(-250) --154 + j*(-200) --242 + j*(-35) --169 + j*(148) -28 + j*(182) -119 + j*(23) --4 + j*(-71) --80 + j*(55) -78 + j*(136) -201 + j*(-40) -51 + j*(-215) --136 + j*(-129) --115 + j*(15) --48 + j*(14) --65 + j*(13) --32 + j*(52) -6 + j*(-6) --92 + j*(-28) --108 + j*(125) -95 + j*(154) -145 + j*(-75) --81 + j*(-149) --168 + j*(36) --63 + j*(98) --88 + j*(78) --85 + j*(232) -168 + j*(283) -300 + j*(21) -99 + j*(-140) --28 + j*(1) -87 + j*(86) -153 + j*(6) -146 + j*(-33) -196 + j*(-98) -144 + j*(-267) --88 + j*(-317) --242 + j*(-145) --199 + j*(22) --127 + j*(65) --105 + j*(106) --24 + j*(184) -145 + j*(170) -253 + j*(-1) -181 + j*(-197) -1 + j*(-265) --160 + j*(-197) --226 + j*(-42) --148 + j*(98) --10 + j*(91) -0 + j*(-11) --71 + j*(-3) --41 + j*(52) --11 + j*(0) --92 + j*(-5) --85 + j*(107) -28 + j*(93) --16 + j*(7) --84 + j*(111) -69 + j*(193) -167 + j*(37) -43 + j*(-35) -47 + j*(66) -161 + j*(-15) -35 + j*(-163) --132 + j*(-27) --15 + j*(130) -108 + j*(49) -64 + j*(-9) -86 + j*(22) -136 + j*(-57) -55 + j*(-124) -25 + j*(-78) -64 + j*(-126) --51 + j*(-210) --187 + j*(-104) --148 + j*(22) --120 + j*(35) --128 + j*(148) -94 + j*(257) -345 + j*(11) -172 + j*(-356) --223 + j*(-314) --296 + j*(6) --100 + j*(103) --70 + j*(-10) --178 + j*(45) --81 + j*(194) -84 + j*(86) --57 + j*(-71) --226 + j*(136) -33 + j*(346) -279 + j*(84) -23 + j*(-144) --164 + j*(141) -165 + j*(317) -367 + j*(-18) -89 + j*(-231) --88 + j*(-35) -35 + j*(93) -132 + j*(57) -219 + j*(1) -264 + j*(-218) --21 + j*(-406) --325 + j*(-150) --140 + j*(187) -168 + j*(58) -76 + j*(-210) --147 + j*(-161) --148 + j*(-8) --74 + j*(6) --89 + j*(-23) --144 + j*(18) --127 + j*(123) -2 + j*(157) -58 + j*(49) --41 + j*(27) --10 + j*(156) -165 + j*(92) -88 + j*(-93) --71 + j*(11) -91 + j*(141) -202 + j*(-65) --13 + j*(-148) --18 + j*(62) -214 + j*(-37) -35 + j*(-320) --281 + j*(-126) --102 + j*(167) -122 + j*(-16) --92 + j*(-170) --205 + j*(63) -10 + j*(156) -71 + j*(-11) --37 + j*(-30) --14 + j*(35) -26 + j*(-16) --26 + j*(-56) --78 + j*(-49) --167 + j*(5) --163 + j*(206) -111 + j*(287) -266 + j*(14) -36 + j*(-153) --81 + j*(48) -132 + j*(109) -180 + j*(-126) --32 + j*(-206) --134 + j*(-86) --135 + j*(-16) --150 + j*(71) --54 + j*(168) -60 + j*(118) -49 + j*(54) -72 + j*(72) -124 + j*(-14) -5 + j*(-96) --78 + j*(39) -68 + j*(103) -100 + j*(-56) --78 + j*(-47) --35 + j*(161) -194 + j*(110) -156 + j*(-115) --33 + j*(-79) -11 + j*(81) -156 + j*(53) -188 + j*(-41) -220 + j*(-119) -189 + j*(-305) --71 + j*(-407) --284 + j*(-194) --153 + j*(18) -1 + j*(-100) --168 + j*(-241) --371 + j*(-59) --262 + j*(197) --33 + j*(185) --1 + j*(25) --129 + j*(-14) --205 + j*(121) --92 + j*(288) -154 + j*(258) -230 + j*(4) -18 + j*(-135) --125 + j*(29) -9 + j*(150) -98 + j*(33) --13 + j*(-10) --10 + j*(112) -136 + j*(90) -122 + j*(-68) --18 + j*(-75) --45 + j*(35) -28 + j*(87) -118 + j*(69) -181 + j*(-52) -69 + j*(-202) --136 + j*(-134) --113 + j*(66) -42 + j*(57) -8 + j*(-47) --66 + j*(23) -25 + j*(87) -83 + j*(7) -42 + j*(-22) -74 + j*(-25) -54 + j*(-136) --122 + j*(-134) --162 + j*(60) -3 + j*(125) -60 + j*(15) --7 + j*(-12) --16 + j*(25) --18 + j*(44) -15 + j*(123) -188 + j*(107) -230 + j*(-129) --8 + j*(-223) --100 + j*(-18) -85 + j*(27) -83 + j*(-168) --118 + j*(-143) --72 + j*(44) -106 + j*(-39) -4 + j*(-240) --216 + j*(-181) --240 + j*(-13) --204 + j*(47) --207 + j*(129) --109 + j*(250) -64 + j*(228) -132 + j*(100) -86 + j*(10) -14 + j*(3) --6 + j*(80) -102 + j*(127) -205 + j*(6) -120 + j*(-132) -23 + j*(-95) -71 + j*(-92) -2 + j*(-221) --213 + j*(-148) --161 + j*(94) -59 + j*(23) --74 + j*(-202) --357 + j*(-33) --240 + j*(288) -18 + j*(272) -37 + j*(175) -105 + j*(233) -291 + j*(98) -181 + j*(-177) --100 + j*(-116) --73 + j*(117) -91 + j*(106) -87 + j*(23) -88 + j*(41) -129 + j*(-18) -35 + j*(-51) -51 + j*(93) -299 + j*(35) -273 + j*(-335) --156 + j*(-414) --351 + j*(-25) --69 + j*(227) -180 + j*(63) -119 + j*(-141) --9 + j*(-163) --68 + j*(-130) --117 + j*(-95) --148 + j*(-23) --117 + j*(53) --54 + j*(87) -18 + j*(79) -74 + j*(8) -27 + j*(-95) --106 + j*(-81) --122 + j*(64) -18 + j*(103) -67 + j*(-23) --38 + j*(-62) --52 + j*(15) --5 + j*(-18) --100 + j*(-43) --124 + j*(118) -87 + j*(151) -124 + j*(-83) --111 + j*(-116) --126 + j*(108) -68 + j*(95) -16 + j*(-65) --108 + j*(23) -4 + j*(105) -25 + j*(-23) --137 + j*(26) --43 + j*(242) -209 + j*(152) -157 + j*(-90) --29 + j*(-62) --1 + j*(57) -65 + j*(22) -33 + j*(-6) -37 + j*(25) -71 + j*(4) -57 + j*(-27) -45 + j*(-31) -33 + j*(-45) -14 + j*(-37) -20 + j*(-40) --26 + j*(-62) --83 + j*(25) -33 + j*(124) -168 + j*(6) -71 + j*(-131) --31 + j*(-49) -61 + j*(-3) -76 + j*(-119) --37 + j*(-129) --37 + j*(-59) --21 + j*(-105) --117 + j*(-103) --119 + j*(0) --52 + j*(-21) --143 + j*(-62) --216 + j*(88) --84 + j*(226) -62 + j*(204) -172 + j*(158) -307 + j*(4) -238 + j*(-293) --97 + j*(-386) --315 + j*(-170) --280 + j*(40) --205 + j*(124) --131 + j*(193) --19 + j*(206) -49 + j*(155) -71 + j*(120) -98 + j*(83) -88 + j*(44) -91 + j*(46) -132 + j*(-2) -78 + j*(-77) -6 + j*(-24) -94 + j*(13) -116 + j*(-141) --91 + j*(-177) --135 + j*(46) -101 + j*(64) -78 + j*(-226) --296 + j*(-205) --355 + j*(235) -74 + j*(406) -328 + j*(66) -108 + j*(-200) --114 + j*(-77) --45 + j*(81) -49 + j*(34) -9 + j*(-13) --10 + j*(21) -1 + j*(23) --32 + j*(61) -52 + j*(161) -234 + j*(83) -208 + j*(-136) -31 + j*(-148) -47 + j*(-47) -117 + j*(-138) --10 + j*(-226) --93 + j*(-142) --71 + j*(-156) --241 + j*(-191) --377 + j*(94) --81 + j*(344) -216 + j*(110) -48 + j*(-162) --172 + j*(-31) --73 + j*(142) -57 + j*(87) -47 + j*(13) -22 + j*(-12) --25 + j*(-16) --24 + j*(68) -117 + j*(53) -107 + j*(-164) --175 + j*(-194) --265 + j*(111) -1 + j*(253) -161 + j*(64) -62 + j*(-62) -4 + j*(-42) --28 + j*(-76) --167 + j*(-33) --160 + j*(195) -110 + j*(252) -217 + j*(-8) --30 + j*(-126) --147 + j*(141) -146 + j*(299) -387 + j*(37) -243 + j*(-246) -35 + j*(-247) --33 + j*(-213) --173 + j*(-204) --295 + j*(11) --115 + j*(234) -114 + j*(135) -74 + j*(-23) -9 + j*(18) -79 + j*(5) -8 + j*(-88) --105 + j*(53) -108 + j*(214) -368 + j*(-23) -211 + j*(-374) --131 + j*(-378) --259 + j*(-180) --253 + j*(-60) --255 + j*(34) --210 + j*(148) --110 + j*(215) -11 + j*(240) -160 + j*(177) -216 + j*(-8) -86 + j*(-150) --68 + j*(-105) --78 + j*(-5) --49 + j*(3) --88 + j*(13) --98 + j*(117) -33 + j*(196) -191 + j*(102) -180 + j*(-88) -23 + j*(-161) --81 + j*(-76) --59 + j*(-5) --49 + j*(-9) --93 + j*(25) --62 + j*(125) -76 + j*(147) -159 + j*(25) -98 + j*(-92) -0 + j*(-98) --47 + j*(-64) --97 + j*(-25) --108 + j*(90) -31 + j*(173) -175 + j*(49) -82 + j*(-114) --69 + j*(-41) --1 + j*(96) -131 + j*(36) -105 + j*(-78) -41 + j*(-94) -9 + j*(-105) --73 + j*(-95) --102 + j*(18) -3 + j*(81) -83 + j*(25) -106 + j*(-34) -129 + j*(-136) -4 + j*(-281) --235 + j*(-223) --278 + j*(6) --155 + j*(91) --127 + j*(73) --122 + j*(136) --34 + j*(174) -15 + j*(154) -86 + j*(183) -236 + j*(89) -199 + j*(-133) -11 + j*(-152) -20 + j*(-77) -4 + j*(-209) --286 + j*(-191) --341 + j*(189) -17 + j*(314) -130 + j*(55) --38 + j*(45) -91 + j*(190) -264 + j*(-47) --21 + j*(-260) --262 + j*(22) --18 + j*(275) -221 + j*(108) -154 + j*(-83) -52 + j*(-103) --15 + j*(-94) --64 + j*(-11) -44 + j*(52) -108 + j*(-109) --117 + j*(-198) --267 + j*(60) --30 + j*(270) -205 + j*(99) -99 + j*(-131) --123 + j*(-71) --119 + j*(173) -160 + j*(271) -397 + j*(8) -227 + j*(-342) --134 + j*(-293) --158 + j*(-21) -2 + j*(-22) --86 + j*(-103) --139 + j*(74) -104 + j*(113) -129 + j*(-175) --195 + j*(-192) --213 + j*(151) -124 + j*(177) -165 + j*(-131) --93 + j*(-189) --161 + j*(-6) --66 + j*(54) --33 + j*(25) --26 + j*(12) --36 + j*(-13) --82 + j*(9) --55 + j*(66) --14 + j*(37) --62 + j*(30) --41 + j*(111) -63 + j*(80) -17 + j*(-19) --72 + j*(60) -42 + j*(157) -161 + j*(45) -98 + j*(-74) -28 + j*(-83) --31 + j*(-104) --149 + j*(-33) --94 + j*(147) -101 + j*(103) -35 + j*(-83) --158 + j*(25) --26 + j*(250) -224 + j*(148) -187 + j*(-78) -29 + j*(-98) --18 + j*(-13) -12 + j*(62) -127 + j*(79) -210 + j*(-69) -71 + j*(-202) --48 + j*(-101) -40 + j*(-66) --28 + j*(-208) --261 + j*(-81) --141 + j*(224) -177 + j*(142) -123 + j*(-127) --58 + j*(-62) -45 + j*(30) -76 + j*(-122) --115 + j*(-110) --59 + j*(100) -177 + j*(4) -77 + j*(-275) --228 + j*(-226) --267 + j*(42) --95 + j*(151) -31 + j*(91) -57 + j*(-20) --27 + j*(-105) --147 + j*(-56) --144 + j*(71) --50 + j*(106) --7 + j*(58) --29 + j*(24) --67 + j*(45) --49 + j*(118) -65 + j*(116) -86 + j*(-36) --112 + j*(-77) --193 + j*(165) -64 + j*(317) -276 + j*(114) -177 + j*(-104) -25 + j*(-93) --6 + j*(-34) --25 + j*(0) -8 + j*(62) -98 + j*(21) -41 + j*(-95) --111 + j*(-27) --52 + j*(167) -162 + j*(155) -220 + j*(-29) -118 + j*(-123) -54 + j*(-117) -21 + j*(-127) --53 + j*(-118) --95 + j*(-32) --35 + j*(44) -45 + j*(13) -33 + j*(-52) --14 + j*(-35) -33 + j*(7) -99 + j*(-81) -2 + j*(-207) --172 + j*(-160) --208 + j*(-7) --146 + j*(72) --112 + j*(112) --35 + j*(176) -103 + j*(151) -158 + j*(18) -99 + j*(-81) -11 + j*(-106) --61 + j*(-59) --44 + j*(31) -65 + j*(18) -53 + j*(-113) --81 + j*(-117) --83 + j*(-16) --30 + j*(-77) --202 + j*(-127) --324 + j*(141) --44 + j*(362) -228 + j*(146) -90 + j*(-93) --62 + j*(8) -55 + j*(76) -70 + j*(-87) --134 + j*(-94) --181 + j*(119) --22 + j*(212) -74 + j*(162) -115 + j*(141) -197 + j*(92) -218 + j*(-27) -170 + j*(-106) -127 + j*(-173) -2 + j*(-251) --190 + j*(-165) --203 + j*(62) --20 + j*(153) -93 + j*(51) -58 + j*(-40) -6 + j*(-46) --22 + j*(-21) --3 + j*(30) -86 + j*(17) -95 + j*(-126) --79 + j*(-179) --173 + j*(-15) --42 + j*(74) --4 + j*(-47) --164 + j*(-27) --126 + j*(191) -116 + j*(171) -101 + j*(-45) --76 + j*(13) -52 + j*(183) -247 + j*(13) -79 + j*(-192) --83 + j*(-44) -78 + j*(41) -103 + j*(-173) --161 + j*(-172) --162 + j*(106) -95 + j*(105) -82 + j*(-119) --99 + j*(-95) --67 + j*(33) --4 + j*(-14) --74 + j*(-21) --40 + j*(69) -55 + j*(6) --31 + j*(-93) --138 + j*(-1) --71 + j*(106) -7 + j*(80) -4 + j*(54) -16 + j*(66) -38 + j*(67) -89 + j*(71) -165 + j*(-13) -92 + j*(-161) --76 + j*(-122) --33 + j*(4) -47 + j*(-105) --160 + j*(-189) --305 + j*(81) --49 + j*(291) -180 + j*(107) -85 + j*(-82) --24 + j*(-65) --71 + j*(-59) --182 + j*(24) --113 + j*(245) -162 + j*(235) -211 + j*(-2) -82 + j*(-57) -105 + j*(-40) -57 + j*(-190) --214 + j*(-143) --218 + j*(195) -119 + j*(257) -211 + j*(-23) --3 + j*(-104) --58 + j*(68) -81 + j*(122) -161 + j*(34) -153 + j*(-53) -96 + j*(-107) -34 + j*(-81) -81 + j*(-36) -146 + j*(-136) -33 + j*(-271) --147 + j*(-221) --185 + j*(-76) --133 + j*(-6) --98 + j*(9) --80 + j*(22) --57 + j*(44) -0 + j*(50) -52 + j*(-19) --2 + j*(-106) --92 + j*(-95) --130 + j*(-57) --187 + j*(-7) --173 + j*(144) -32 + j*(171) -71 + j*(-71) --226 + j*(-107) --287 + j*(241) -47 + j*(349) -146 + j*(107) -4 + j*(114) -156 + j*(236) -326 + j*(-4) -98 + j*(-211) --76 + j*(-43) -40 + j*(45) -30 + j*(-45) --41 + j*(55) -136 + j*(119) -220 + j*(-103) -8 + j*(-214) --111 + j*(-71) --53 + j*(21) --6 + j*(43) -85 + j*(30) -97 + j*(-129) --117 + j*(-163) --171 + j*(70) -44 + j*(124) -54 + j*(-39) --52 + j*(37) -140 + j*(110) -220 + j*(-192) --144 + j*(-316) --315 + j*(39) --25 + j*(219) -111 + j*(18) --19 + j*(-42) -4 + j*(44) -74 + j*(-40) --48 + j*(-110) --127 + j*(16) --18 + j*(100) -57 + j*(18) --7 + j*(-45) --74 + j*(11) --25 + j*(96) -80 + j*(71) -81 + j*(-37) --18 + j*(-50) --22 + j*(45) -85 + j*(44) -107 + j*(-78) --13 + j*(-150) --145 + j*(-63) --115 + j*(125) -119 + j*(172) -253 + j*(-79) -37 + j*(-286) --185 + j*(-141) --96 + j*(16) --42 + j*(-79) --195 + j*(-61) --161 + j*(144) -57 + j*(105) --1 + j*(-112) --246 + j*(-51) --245 + j*(218) --22 + j*(330) -162 + j*(235) -211 + j*(70) -119 + j*(-49) -3 + j*(-13) -25 + j*(96) -150 + j*(94) -206 + j*(-46) -86 + j*(-180) --112 + j*(-100) --64 + j*(151) -252 + j*(136) -301 + j*(-232) --54 + j*(-372) --244 + j*(-119) --134 + j*(26) --115 + j*(15) --107 + j*(129) -71 + j*(166) -145 + j*(18) -98 + j*(-38) -134 + j*(-103) --1 + j*(-272) --283 + j*(-120) --150 + j*(210) -165 + j*(83) -21 + j*(-183) --189 + j*(-12) --2 + j*(131) -64 + j*(-58) --126 + j*(-49) --59 + j*(136) -103 + j*(37) --17 + j*(-81) --87 + j*(56) -59 + j*(99) -103 + j*(-33) -22 + j*(-93) --52 + j*(-93) --134 + j*(-23) --73 + j*(110) -72 + j*(34) --58 + j*(-106) --211 + j*(92) -29 + j*(271) -210 + j*(41) -16 + j*(-95) --42 + j*(75) -119 + j*(57) -55 + j*(-96) --86 + j*(-13) --23 + j*(100) -32 + j*(108) -118 + j*(181) -371 + j*(95) -402 + j*(-281) -74 + j*(-475) --175 + j*(-357) --277 + j*(-229) --358 + j*(-48) --234 + j*(166) --27 + j*(107) --109 + j*(-28) --217 + j*(129) --30 + j*(271) -136 + j*(125) -71 + j*(-9) --1 + j*(-15) --70 + j*(-4) --133 + j*(132) -42 + j*(294) -303 + j*(142) -223 + j*(-158) --55 + j*(-142) --59 + j*(102) -181 + j*(112) -231 + j*(-144) --11 + j*(-252) --147 + j*(-62) -1 + j*(39) -33 + j*(-119) --177 + j*(-115) --193 + j*(136) -23 + j*(185) -57 + j*(69) -38 + j*(128) -215 + j*(129) -273 + j*(-96) -122 + j*(-198) -69 + j*(-190) --35 + j*(-276) --267 + j*(-134) --122 + j*(179) -229 + j*(28) -83 + j*(-345) --271 + j*(-250) --245 + j*(-14) --210 + j*(-30) --313 + j*(112) --86 + j*(327) -173 + j*(93) --69 + j*(-135) --255 + j*(141) -42 + j*(303) -182 + j*(20) --82 + j*(-75) --145 + j*(193) -121 + j*(270) -237 + j*(54) -108 + j*(-70) -25 + j*(-13) -55 + j*(12) -28 + j*(-23) --34 + j*(63) -120 + j*(189) -352 + j*(4) -215 + j*(-322) --115 + j*(-276) --127 + j*(-49) --33 + j*(-69) --134 + j*(-77) --108 + j*(78) -27 + j*(11) --137 + j*(-69) --186 + j*(235) -243 + j*(309) -369 + j*(-182) --112 + j*(-344) --274 + j*(80) -69 + j*(216) -162 + j*(-28) -27 + j*(-59) -87 + j*(-18) -86 + j*(-177) --136 + j*(-192) --197 + j*(26) --31 + j*(121) -74 + j*(19) -27 + j*(-87) --86 + j*(-85) --127 + j*(34) --18 + j*(105) -66 + j*(24) -24 + j*(-49) --16 + j*(-54) --59 + j*(-66) --125 + j*(-4) --54 + j*(88) -26 + j*(-8) --124 + j*(-73) --205 + j*(136) -11 + j*(251) -134 + j*(88) -36 + j*(11) -19 + j*(73) -58 + j*(71) -84 + j*(89) -207 + j*(41) -176 + j*(-191) --116 + j*(-194) --131 + j*(103) -144 + j*(100) -114 + j*(-139) --59 + j*(-81) -41 + j*(-2) -23 + j*(-161) --189 + j*(-74) --52 + j*(148) -144 + j*(-46) --123 + j*(-207) --264 + j*(122) -91 + j*(254) -206 + j*(-91) --107 + j*(-187) --196 + j*(83) -6 + j*(176) -105 + j*(62) -81 + j*(-24) -15 + j*(-57) --35 + j*(6) -52 + j*(47) -86 + j*(-85) --80 + j*(-120) --107 + j*(52) -46 + j*(39) --36 + j*(-94) --171 + j*(52) -12 + j*(190) -124 + j*(6) --62 + j*(-54) --77 + j*(151) -130 + j*(168) -180 + j*(26) -166 + j*(-25) -178 + j*(-141) --4 + j*(-233) --127 + j*(-46) -69 + j*(38) -97 + j*(-207) --206 + j*(-209) --213 + j*(114) -80 + j*(118) -58 + j*(-122) --129 + j*(-64) --42 + j*(75) -59 + j*(-29) --37 + j*(-95) --54 + j*(-34) --23 + j*(-101) --174 + j*(-157) --306 + j*(5) --240 + j*(180) --135 + j*(243) --26 + j*(291) -132 + j*(257) -208 + j*(124) -208 + j*(8) -157 + j*(-139) --93 + j*(-210) --298 + j*(95) -19 + j*(426) -450 + j*(151) -264 + j*(-317) --165 + j*(-221) --127 + j*(117) -110 + j*(104) -114 + j*(-34) -76 + j*(-50) -64 + j*(-108) --61 + j*(-112) --74 + j*(44) -88 + j*(50) -76 + j*(-103) --59 + j*(-65) -11 + j*(50) -115 + j*(-42) -33 + j*(-141) --35 + j*(-100) --25 + j*(-98) --86 + j*(-113) --129 + j*(-36) --80 + j*(10) --71 + j*(-4) --76 + j*(33) --16 + j*(42) --2 + j*(-22) --56 + j*(-44) --93 + j*(-27) --144 + j*(9) --151 + j*(122) --30 + j*(186) -37 + j*(105) --25 + j*(115) -68 + j*(235) -293 + j*(144) -298 + j*(-127) -99 + j*(-245) --52 + j*(-191) --116 + j*(-89) --85 + j*(19) -25 + j*(21) -33 + j*(-80) --43 + j*(-100) --53 + j*(-90) --119 + j*(-156) --303 + j*(-93) --355 + j*(148) --214 + j*(329) --27 + j*(395) -199 + j*(349) -314 + j*(112) -151 + j*(-49) -52 + j*(86) -244 + j*(121) -284 + j*(-127) -49 + j*(-185) -27 + j*(2) -211 + j*(-42) -151 + j*(-265) --82 + j*(-264) --145 + j*(-88) --41 + j*(-4) -49 + j*(-73) --9 + j*(-200) --190 + j*(-180) --232 + j*(2) --119 + j*(68) --112 + j*(33) --122 + j*(126) -45 + j*(161) -108 + j*(-21) --56 + j*(-84) --106 + j*(52) --6 + j*(88) -16 + j*(47) -35 + j*(50) -67 + j*(-11) --2 + j*(-44) -1 + j*(21) -67 + j*(-56) --99 + j*(-135) --204 + j*(109) -81 + j*(243) -216 + j*(-44) --47 + j*(-130) -64 + j*(-24) -41 + j*(-137) --82 + j*(-142) --141 + j*(-64) --153 + j*(28) --67 + j*(131) -93 + j*(62) -26 + j*(-125) --173 + j*(-42) --63 + j*(158) -138 + j*(8) --60 + j*(-206) --307 + j*(6) --136 + j*(267) -69 + j*(159) --29 + j*(66) --37 + j*(230) -202 + j*(243) -265 + j*(5) -98 + j*(-65) -90 + j*(48) -213 + j*(-6) -160 + j*(-149) -56 + j*(-121) -119 + j*(-106) -91 + j*(-280) --187 + j*(-302) --305 + j*(-4) --69 + j*(175) -116 + j*(18) -30 + j*(-141) --93 + j*(-135) --163 + j*(-81) --216 + j*(28) --139 + j*(171) -18 + j*(165) -49 + j*(78) -57 + j*(83) -155 + j*(21) -103 + j*(-164) --122 + j*(-168) --175 + j*(40) --28 + j*(109) -23 + j*(23) --23 + j*(6) --10 + j*(32) -2 + j*(1) --35 + j*(-1) --23 + j*(35) -13 + j*(-4) --66 + j*(-68) --210 + j*(28) --175 + j*(274) -111 + j*(379) -349 + j*(170) -293 + j*(-82) -161 + j*(-128) -151 + j*(-157) -40 + j*(-276) --187 + j*(-195) --172 + j*(47) -14 + j*(54) --13 + j*(-79) --132 + j*(-13) --64 + j*(110) -35 + j*(85) -52 + j*(49) -99 + j*(15) -79 + j*(-91) --39 + j*(-89) --27 + j*(5) -39 + j*(-52) --76 + j*(-105) --136 + j*(44) -11 + j*(106) -51 + j*(-4) --18 + j*(1) -37 + j*(23) -4 + j*(-74) --138 + j*(35) -53 + j*(249) -366 + j*(14) -157 + j*(-379) --248 + j*(-250) --188 + j*(83) -41 + j*(38) --22 + j*(-115) --141 + j*(-55) --129 + j*(31) --105 + j*(80) --28 + j*(122) -49 + j*(49) --32 + j*(-14) --62 + j*(99) -91 + j*(110) -94 + j*(-57) --52 + j*(-32) -41 + j*(77) -134 + j*(-120) --168 + j*(-247) --377 + j*(124) --13 + j*(419) -333 + j*(126) -125 + j*(-203) --144 + j*(-54) --21 + j*(157) -153 + j*(50) -77 + j*(-89) --10 + j*(-42) -33 + j*(-24) --8 + j*(-95) --121 + j*(-30) --54 + j*(96) -50 + j*(21) --81 + j*(-54) --167 + j*(165) -110 + j*(319) -340 + j*(62) -156 + j*(-168) -14 + j*(-24) -199 + j*(27) -245 + j*(-236) --26 + j*(-341) --163 + j*(-165) --98 + j*(-92) --140 + j*(-118) --202 + j*(-4) --97 + j*(97) --11 + j*(29) --64 + j*(-8) --75 + j*(61) -6 + j*(84) -62 + j*(32) -72 + j*(-46) -13 + j*(-127) --112 + j*(-111) --132 + j*(13) --25 + j*(25) --56 + j*(-96) --250 + j*(-49) --264 + j*(226) -14 + j*(361) -247 + j*(173) -189 + j*(-72) -2 + j*(-122) --89 + j*(-29) --75 + j*(69) --3 + j*(126) -95 + j*(119) -141 + j*(39) -118 + j*(-20) -115 + j*(-37) -116 + j*(-103) -31 + j*(-166) --64 + j*(-118) --65 + j*(-54) --66 + j*(-45) --90 + j*(16) -6 + j*(77) -94 + j*(-42) --61 + j*(-146) --194 + j*(41) -13 + j*(211) -212 + j*(1) -8 + j*(-216) --228 + j*(-27) --75 + j*(230) -174 + j*(141) -160 + j*(-45) -83 + j*(-62) -115 + j*(-94) -39 + j*(-226) --177 + j*(-192) --229 + j*(41) --44 + j*(156) -86 + j*(37) -6 + j*(-76) --101 + j*(-11) --45 + j*(110) -105 + j*(72) -92 + j*(-110) --130 + j*(-128) --197 + j*(137) -96 + j*(279) -316 + j*(0) -93 + j*(-269) --172 + j*(-113) --61 + j*(115) -125 + j*(30) -73 + j*(-115) -4 + j*(-102) -11 + j*(-150) --149 + j*(-238) --384 + j*(-59) --305 + j*(295) -54 + j*(376) -254 + j*(119) -124 + j*(-99) --45 + j*(-50) --22 + j*(57) -33 + j*(26) --25 + j*(24) -21 + j*(144) -226 + j*(79) -194 + j*(-200) --114 + j*(-233) --198 + j*(49) -19 + j*(156) -126 + j*(13) -56 + j*(-76) --11 + j*(-73) --66 + j*(-25) --28 + j*(86) -134 + j*(58) -122 + j*(-135) --61 + j*(-136) --48 + j*(8) -57 + j*(-56) --45 + j*(-141) --107 + j*(-39) --30 + j*(-52) --159 + j*(-131) --292 + j*(89) --57 + j*(279) -117 + j*(89) --38 + j*(10) -1 + j*(186) -231 + j*(69) -86 + j*(-197) --174 + j*(-53) --38 + j*(173) -136 + j*(46) -21 + j*(-68) --37 + j*(43) -69 + j*(60) -68 + j*(-39) --21 + j*(-29) --25 + j*(62) -76 + j*(116) -218 + j*(29) -185 + j*(-206) --100 + j*(-251) --214 + j*(39) -54 + j*(186) -209 + j*(-40) -37 + j*(-188) --83 + j*(-73) --18 + j*(6) -35 + j*(-20) -56 + j*(-64) -25 + j*(-142) --98 + j*(-144) --122 + j*(-19) --17 + j*(-11) --58 + j*(-113) --182 + j*(-39) --112 + j*(105) -23 + j*(50) --20 + j*(-59) --103 + j*(-37) --104 + j*(3) --135 + j*(6) --189 + j*(83) --144 + j*(216) -12 + j*(267) -136 + j*(172) -117 + j*(60) -77 + j*(79) -180 + j*(68) -186 + j*(-144) --102 + j*(-214) --239 + j*(102) -61 + j*(281) -254 + j*(25) -56 + j*(-141) --49 + j*(6) -57 + j*(30) --7 + j*(-59) --101 + j*(93) -103 + j*(225) -279 + j*(25) -134 + j*(-156) -2 + j*(-59) -90 + j*(11) -130 + j*(-89) -39 + j*(-122) -33 + j*(-61) -78 + j*(-105) --21 + j*(-170) --120 + j*(-28) -64 + j*(127) -313 + j*(-81) -153 + j*(-427) --210 + j*(-384) --231 + j*(-131) --118 + j*(-202) --387 + j*(-298) --633 + j*(100) --279 + j*(514) -172 + j*(310) -67 + j*(-50) --197 + j*(56) --66 + j*(297) -193 + j*(192) -164 + j*(-54) --28 + j*(-98) --116 + j*(18) --81 + j*(117) --19 + j*(151) -37 + j*(168) -129 + j*(162) -209 + j*(63) -163 + j*(-70) -45 + j*(-78) -25 + j*(6) -100 + j*(17) -131 + j*(-62) -88 + j*(-138) --5 + j*(-174) --111 + j*(-132) --146 + j*(-30) --123 + j*(44) --94 + j*(106) -11 + j*(177) -171 + j*(91) -123 + j*(-115) --89 + j*(-86) --54 + j*(130) -180 + j*(79) -123 + j*(-181) --157 + j*(-134) --135 + j*(154) -141 + j*(170) -193 + j*(-69) -15 + j*(-131) --30 + j*(-1) -87 + j*(23) -130 + j*(-98) -33 + j*(-192) --98 + j*(-163) --141 + j*(-40) --41 + j*(35) -35 + j*(-76) --122 + j*(-187) --322 + j*(-10) --206 + j*(290) -116 + j*(298) -231 + j*(49) -106 + j*(-91) -16 + j*(-54) -35 + j*(-28) -39 + j*(-62) -7 + j*(-80) --8 + j*(-82) --33 + j*(-113) --124 + j*(-127) --225 + j*(-24) --181 + j*(148) --6 + j*(187) -78 + j*(68) -18 + j*(-5) --16 + j*(27) -11 + j*(34) -21 + j*(15) -33 + j*(-19) --19 + j*(-102) --199 + j*(-66) --223 + j*(192) -48 + j*(288) -165 + j*(59) --33 + j*(-6) --26 + j*(218) -255 + j*(191) -272 + j*(-114) -8 + j*(-186) --96 + j*(-7) --14 + j*(115) -115 + j*(137) -253 + j*(25) -185 + j*(-202) --76 + j*(-175) --47 + j*(91) -243 + j*(33) -178 + j*(-313) --200 + j*(-301) --272 + j*(54) --1 + j*(194) -169 + j*(40) -136 + j*(-121) -37 + j*(-179) --43 + j*(-160) --63 + j*(-138) --114 + j*(-163) --235 + j*(-103) --231 + j*(80) --65 + j*(129) --11 + j*(6) --116 + j*(-33) --173 + j*(54) --153 + j*(148) --80 + j*(243) -95 + j*(272) -233 + j*(119) -171 + j*(-49) -55 + j*(-51) -62 + j*(1) -98 + j*(-42) -52 + j*(-112) --40 + j*(-102) --72 + j*(-16) -1 + j*(43) -81 + j*(-20) -53 + j*(-125) --43 + j*(-179) --188 + j*(-168) --325 + j*(2) --218 + j*(263) -74 + j*(243) -76 + j*(-13) --163 + j*(36) --66 + j*(303) -223 + j*(214) -158 + j*(-27) -11 + j*(62) -166 + j*(144) -234 + j*(-49) -67 + j*(-89) -112 + j*(40) -257 + j*(-106) -83 + j*(-316) --161 + j*(-204) --150 + j*(-12) --67 + j*(54) -35 + j*(88) -170 + j*(-28) -55 + j*(-238) --200 + j*(-151) --151 + j*(99) -42 + j*(74) -9 + j*(-31) --1 + j*(45) -143 + j*(-13) -63 + j*(-231) --192 + j*(-179) --185 + j*(47) --30 + j*(47) --66 + j*(-51) --162 + j*(28) --84 + j*(158) -79 + j*(127) -111 + j*(-55) --77 + j*(-161) --276 + j*(13) --178 + j*(303) -132 + j*(349) -320 + j*(135) -297 + j*(-108) -119 + j*(-267) --125 + j*(-216) --168 + j*(18) -16 + j*(81) -48 + j*(-74) --92 + j*(-81) --94 + j*(18) --81 + j*(-3) --179 + j*(80) --57 + j*(281) -202 + j*(188) -150 + j*(-26) -40 + j*(47) -203 + j*(78) -226 + j*(-163) -0 + j*(-209) --13 + j*(-86) -6 + j*(-194) --262 + j*(-181) --286 + j*(189) -80 + j*(265) -151 + j*(-21) --35 + j*(-16) -78 + j*(108) -181 + j*(-91) --48 + j*(-185) --113 + j*(24) -58 + j*(37) -21 + j*(-93) --57 + j*(-22) -38 + j*(-23) --54 + j*(-161) --253 + j*(-11) --105 + j*(243) -149 + j*(144) -117 + j*(-54) -15 + j*(-83) --57 + j*(-91) --180 + j*(6) --98 + j*(235) -189 + j*(204) -222 + j*(-64) -36 + j*(-125) --2 + j*(-39) -12 + j*(-47) --20 + j*(-14) -54 + j*(13) -81 + j*(-112) --78 + j*(-156) --151 + j*(-22) --98 + j*(49) --86 + j*(112) -76 + j*(211) -308 + j*(4) -122 + j*(-337) --262 + j*(-223) --233 + j*(119) -6 + j*(144) -40 + j*(33) -45 + j*(11) -43 + j*(-90) --130 + j*(-105) --162 + j*(110) -53 + j*(146) -67 + j*(-40) --78 + j*(-10) --3 + j*(91) -42 + j*(-25) --122 + j*(-4) --47 + j*(221) -228 + j*(124) -138 + j*(-163) --124 + j*(-83) --40 + j*(128) -112 + j*(25) --30 + j*(-65) --81 + j*(145) -210 + j*(213) -359 + j*(-129) -35 + j*(-382) --292 + j*(-139) --144 + j*(200) -153 + j*(124) -97 + j*(-101) --52 + j*(-10) -112 + j*(100) -239 + j*(-129) -11 + j*(-296) --152 + j*(-137) --54 + j*(-61) --98 + j*(-168) --269 + j*(-66) --192 + j*(139) --30 + j*(98) --91 + j*(12) --161 + j*(124) --47 + j*(248) -115 + j*(233) -236 + j*(119) -250 + j*(-72) -95 + j*(-197) --52 + j*(-136) --57 + j*(-49) --47 + j*(-37) --54 + j*(-12) --31 + j*(-16) --93 + j*(-37) --151 + j*(93) -11 + j*(206) -153 + j*(60) -35 + j*(-54) --14 + j*(54) -110 + j*(35) -32 + j*(-99) --103 + j*(47) -114 + j*(197) -316 + j*(-71) -65 + j*(-332) --214 + j*(-156) --134 + j*(71) --4 + j*(54) -1 + j*(30) -66 + j*(43) -121 + j*(-80) --9 + j*(-190) --156 + j*(-113) --150 + j*(11) --104 + j*(44) --106 + j*(69) --71 + j*(145) -52 + j*(167) -144 + j*(62) -97 + j*(-61) --7 + j*(-66) --28 + j*(-11) --20 + j*(-7) --63 + j*(14) --44 + j*(110) -88 + j*(124) -147 + j*(-8) -36 + j*(-94) --58 + j*(1) -39 + j*(115) -204 + j*(23) -161 + j*(-202) --83 + j*(-239) --188 + j*(-33) --38 + j*(81) -49 + j*(-44) --83 + j*(-132) --227 + j*(-7) --192 + j*(210) -33 + j*(340) -315 + j*(206) -324 + j*(-126) -49 + j*(-216) --6 + j*(-18) -190 + j*(-70) -64 + j*(-332) --242 + j*(-202) --119 + j*(66) -68 + j*(-121) --240 + j*(-272) --431 + j*(117) --62 + j*(359) -168 + j*(81) --14 + j*(-62) --42 + j*(56) -35 + j*(-28) --143 + j*(-83) --199 + j*(154) -36 + j*(207) -38 + j*(9) --150 + j*(108) -25 + j*(344) -317 + j*(180) -221 + j*(-98) -23 + j*(-40) -105 + j*(94) -245 + j*(-13) -183 + j*(-194) -4 + j*(-231) --112 + j*(-112) --64 + j*(18) -39 + j*(7) -29 + j*(-66) --8 + j*(-44) -40 + j*(-46) -14 + j*(-140) --119 + j*(-122) --127 + j*(6) --47 + j*(11) --90 + j*(-26) --123 + j*(74) --8 + j*(132) -60 + j*(39) --11 + j*(-6) --38 + j*(69) -47 + j*(123) -156 + j*(77) -216 + j*(-64) -124 + j*(-233) --90 + j*(-257) --214 + j*(-104) --177 + j*(40) --98 + j*(95) --26 + j*(106) -40 + j*(76) -68 + j*(6) -35 + j*(-67) --59 + j*(-93) --153 + j*(0) --78 + j*(149) -103 + j*(101) -69 + j*(-101) --152 + j*(-82) --163 + j*(154) -59 + j*(207) -144 + j*(28) -11 + j*(-62) --85 + j*(35) --25 + j*(155) -107 + j*(158) -172 + j*(62) -152 + j*(-12) -137 + j*(-38) -126 + j*(-89) -62 + j*(-109) -65 + j*(-64) -127 + j*(-144) --11 + j*(-286) --241 + j*(-156) --163 + j*(96) -54 + j*(46) --8 + j*(-119) --135 + j*(-46) --76 + j*(45) --47 + j*(12) --54 + j*(60) -71 + j*(45) -36 + j*(-161) --245 + j*(-125) --243 + j*(197) -57 + j*(221) -52 + j*(-16) --157 + j*(70) --7 + j*(316) -300 + j*(180) -240 + j*(-146) --49 + j*(-164) --121 + j*(78) -91 + j*(207) -287 + j*(41) -203 + j*(-204) --25 + j*(-200) --50 + j*(-33) -74 + j*(-29) -61 + j*(-146) --47 + j*(-156) --89 + j*(-97) --93 + j*(-52) --59 + j*(-19) --25 + j*(-72) --133 + j*(-123) --226 + j*(28) --69 + j*(151) -38 + j*(-12) --158 + j*(-95) --256 + j*(132) --58 + j*(262) -54 + j*(157) -24 + j*(139) -112 + j*(168) -187 + j*(37) -86 + j*(-59) -16 + j*(0) -59 + j*(20) -46 + j*(-21) --2 + j*(8) -18 + j*(72) -103 + j*(110) -242 + j*(49) -283 + j*(-177) -63 + j*(-349) --171 + j*(-238) --180 + j*(-73) --181 + j*(-31) --218 + j*(127) -13 + j*(308) -317 + j*(100) -180 + j*(-249) --138 + j*(-177) --78 + j*(81) -146 + j*(-2) -57 + j*(-236) --176 + j*(-192) --194 + j*(-18) --125 + j*(-6) --196 + j*(-15) --239 + j*(140) --93 + j*(263) -40 + j*(199) -26 + j*(161) -98 + j*(230) -284 + j*(135) -255 + j*(-117) -28 + j*(-158) --29 + j*(-4) -69 + j*(37) -98 + j*(-4) -141 + j*(-21) -175 + j*(-158) --8 + j*(-275) --180 + j*(-100) --18 + j*(64) -117 + j*(-118) --94 + j*(-255) --248 + j*(-61) --112 + j*(74) --43 + j*(-29) --158 + j*(-42) --182 + j*(93) --77 + j*(161) -21 + j*(132) -57 + j*(35) --44 + j*(-43) --165 + j*(81) --31 + j*(267) -203 + j*(157) -128 + j*(-79) --87 + j*(-9) --4 + j*(209) -245 + j*(149) -262 + j*(-107) -58 + j*(-215) --103 + j*(-107) --89 + j*(53) -44 + j*(110) -147 + j*(25) -136 + j*(-93) -44 + j*(-163) --94 + j*(-143) --162 + j*(35) -33 + j*(192) -276 + j*(1) -118 + j*(-319) --238 + j*(-221) --201 + j*(113) -76 + j*(107) -74 + j*(-97) --54 + j*(-91) --29 + j*(-59) --99 + j*(-143) --282 + j*(-12) --161 + j*(262) -140 + j*(199) -129 + j*(-60) --64 + j*(-62) --53 + j*(68) -25 + j*(51) -6 + j*(24) -28 + j*(52) -80 + j*(-8) -14 + j*(-88) --90 + j*(-59) --140 + j*(35) --114 + j*(186) -98 + j*(286) -330 + j*(91) -204 + j*(-202) --58 + j*(-122) -52 + j*(80) -236 + j*(-100) -20 + j*(-310) --190 + j*(-115) --12 + j*(36) -76 + j*(-176) --187 + j*(-270) --344 + j*(-37) --238 + j*(147) --126 + j*(180) --33 + j*(186) -35 + j*(103) --52 + j*(49) --85 + j*(202) -136 + j*(264) -256 + j*(45) -103 + j*(-90) -21 + j*(-9) -54 + j*(-2) --6 + j*(-4) -35 + j*(121) -237 + j*(49) -168 + j*(-221) --132 + j*(-182) --128 + j*(100) -96 + j*(123) -135 + j*(-8) -127 + j*(-30) -165 + j*(-132) -10 + j*(-247) --133 + j*(-87) -42 + j*(19) -100 + j*(-223) --222 + j*(-286) --333 + j*(62) --33 + j*(204) -95 + j*(-21) --64 + j*(-117) --130 + j*(-28) --133 + j*(-2) --188 + j*(76) --101 + j*(226) -95 + j*(206) -155 + j*(47) -94 + j*(-64) --34 + j*(-110) --178 + j*(15) --74 + j*(246) -210 + j*(184) -187 + j*(-86) --14 + j*(-54) -100 + j*(81) -223 + j*(-134) --47 + j*(-290) --216 + j*(-41) --10 + j*(69) --2 + j*(-136) --267 + j*(-77) --235 + j*(247) -64 + j*(313) -211 + j*(148) -238 + j*(6) -191 + j*(-171) --45 + j*(-252) --218 + j*(-37) --59 + j*(169) -144 + j*(66) -88 + j*(-122) --86 + j*(-115) --136 + j*(40) --5 + j*(144) -148 + j*(40) -75 + j*(-150) --138 + j*(-115) --154 + j*(91) --1 + j*(159) -87 + j*(103) -144 + j*(42) -158 + j*(-103) --23 + j*(-199) --171 + j*(-38) --54 + j*(110) -37 + j*(25) --58 + j*(23) -9 + j*(170) -218 + j*(90) -172 + j*(-133) --3 + j*(-113) -45 + j*(-8) -119 + j*(-112) --10 + j*(-196) --89 + j*(-106) --42 + j*(-93) --127 + j*(-153) --262 + j*(-16) --144 + j*(182) -47 + j*(115) --1 + j*(-23) --86 + j*(62) -46 + j*(127) -110 + j*(-31) --53 + j*(-82) --69 + j*(88) -113 + j*(64) -59 + j*(-134) --136 + j*(-60) --41 + j*(107) -82 + j*(-21) --89 + j*(-90) --97 + j*(122) -169 + j*(59) -45 + j*(-286) --397 + j*(-161) --355 + j*(334) -84 + j*(410) -231 + j*(128) -119 + j*(5) -63 + j*(3) -4 + j*(25) -30 + j*(139) -221 + j*(116) -240 + j*(-124) -23 + j*(-187) --40 + j*(-53) -13 + j*(-55) --84 + j*(-57) --74 + j*(125) -165 + j*(130) -197 + j*(-127) --37 + j*(-181) --86 + j*(2) -45 + j*(20) -16 + j*(-74) --71 + j*(1) -35 + j*(109) -179 + j*(11) -139 + j*(-147) -26 + j*(-174) --8 + j*(-152) --52 + j*(-191) --188 + j*(-172) --266 + j*(3) --136 + j*(168) -52 + j*(132) -100 + j*(-23) -17 + j*(-127) --110 + j*(-131) --202 + j*(-24) --151 + j*(117) --20 + j*(118) --13 + j*(30) --76 + j*(63) --2 + j*(139) -105 + j*(52) -33 + j*(-74) --95 + j*(-33) --92 + j*(82) --8 + j*(115) -42 + j*(70) -19 + j*(27) --23 + j*(67) -59 + j*(145) -216 + j*(42) -144 + j*(-204) --153 + j*(-209) --245 + j*(70) --40 + j*(204) -59 + j*(79) --44 + j*(63) -1 + j*(219) -226 + j*(186) -257 + j*(-53) -64 + j*(-124) -5 + j*(14) -122 + j*(37) -124 + j*(-71) -35 + j*(-55) -83 + j*(21) -177 + j*(-45) -146 + j*(-151) -92 + j*(-190) -26 + j*(-250) --139 + j*(-231) --185 + j*(-25) -24 + j*(56) -122 + j*(-159) --81 + j*(-301) --264 + j*(-180) --276 + j*(-36) --257 + j*(64) --177 + j*(170) --37 + j*(166) --4 + j*(84) --8 + j*(76) -38 + j*(30) --32 + j*(-66) --163 + j*(13) --101 + j*(153) -1 + j*(117) --42 + j*(90) --12 + j*(180) -119 + j*(151) -118 + j*(46) -96 + j*(48) -146 + j*(-9) -49 + j*(-115) --74 + j*(-1) -65 + j*(105) -148 + j*(-71) --60 + j*(-138) --116 + j*(88) -109 + j*(135) -158 + j*(-69) -0 + j*(-125) --55 + j*(-34) --37 + j*(9) --11 + j*(54) -79 + j*(37) -63 + j*(-92) --106 + j*(-74) --110 + j*(134) -105 + j*(196) -244 + j*(34) -192 + j*(-152) -17 + j*(-219) --125 + j*(-83) --1 + j*(95) -216 + j*(-44) -77 + j*(-322) --231 + j*(-233) --198 + j*(36) --13 + j*(4) --98 + j*(-134) --258 + j*(-17) --184 + j*(182) -8 + j*(197) -91 + j*(61) -1 + j*(-35) --86 + j*(46) -16 + j*(127) -89 + j*(-1) --80 + j*(-47) --95 + j*(187) -206 + j*(194) -231 + j*(-133) --62 + j*(-153) --21 + j*(76) -164 + j*(-67) --66 + j*(-256) --270 + j*(-5) --62 + j*(169) -6 + j*(22) --118 + j*(103) -91 + j*(258) -290 + j*(-17) -15 + j*(-226) --156 + j*(23) -66 + j*(129) -97 + j*(-69) --72 + j*(-26) -34 + j*(121) -175 + j*(-28) -25 + j*(-163) --91 + j*(-52) --42 + j*(16) --49 + j*(22) --19 + j*(124) -164 + j*(124) -243 + j*(-84) -98 + j*(-250) --100 + j*(-234) --218 + j*(-77) --147 + j*(123) -78 + j*(139) -161 + j*(-71) -4 + j*(-197) --129 + j*(-128) --143 + j*(-45) --141 + j*(2) --122 + j*(45) --107 + j*(54) --117 + j*(101) --40 + j*(161) -40 + j*(84) --67 + j*(37) --97 + j*(231) -188 + j*(313) -370 + j*(17) -158 + j*(-226) --66 + j*(-129) --54 + j*(23) -35 + j*(68) -139 + j*(27) -158 + j*(-143) --45 + j*(-235) --185 + j*(-54) --51 + j*(61) --35 + j*(-49) --178 + j*(45) --4 + j*(259) -267 + j*(54) -59 + j*(-241) --228 + j*(-37) --34 + j*(224) -180 + j*(54) -35 + j*(-87) --25 + j*(50) -119 + j*(49) -84 + j*(-80) -0 + j*(-6) -139 + j*(39) -206 + j*(-162) -13 + j*(-283) --124 + j*(-184) --116 + j*(-117) --155 + j*(-119) --226 + j*(-56) --247 + j*(66) --173 + j*(209) -42 + j*(250) -177 + j*(32) --29 + j*(-141) --209 + j*(83) -45 + j*(274) -258 + j*(11) -16 + j*(-204) --165 + j*(-1) --2 + j*(117) -32 + j*(-23) --111 + j*(28) --8 + j*(192) -165 + j*(91) -99 + j*(-37) -73 + j*(5) -147 + j*(-90) --31 + j*(-238) --258 + j*(-49) --117 + j*(214) -118 + j*(139) -89 + j*(-19) -11 + j*(0) -40 + j*(21) -35 + j*(-11) -9 + j*(13) -49 + j*(36) -94 + j*(3) -107 + j*(-69) -24 + j*(-164) --161 + j*(-100) --141 + j*(158) -157 + j*(201) -267 + j*(-76) -83 + j*(-209) -10 + j*(-151) --16 + j*(-212) --202 + j*(-191) --211 + j*(35) --29 + j*(13) --168 + j*(-146) --388 + j*(119) --94 + j*(441) -273 + j*(221) -144 + j*(-82) --36 + j*(16) -87 + j*(100) -141 + j*(-43) -18 + j*(-96) --24 + j*(-37) --25 + j*(-23) --53 + j*(13) --23 + j*(74) -40 + j*(106) -163 + j*(103) -291 + j*(-91) -100 + j*(-375) --272 + j*(-255) --221 + j*(100) -53 + j*(44) --82 + j*(-169) --295 + j*(35) --92 + j*(264) -97 + j*(131) -34 + j*(59) -103 + j*(104) -171 + j*(-62) --25 + j*(-145) --67 + j*(46) -138 + j*(-2) -1 + j*(-266) --345 + j*(-102) --222 + j*(293) -151 + j*(245) -151 + j*(-49) --62 + j*(-60) --69 + j*(107) -81 + j*(129) -144 + j*(-4) -32 + j*(-121) --141 + j*(-47) --134 + j*(176) -87 + j*(270) -281 + j*(137) -303 + j*(-72) -185 + j*(-235) --19 + j*(-260) --150 + j*(-108) --71 + j*(45) -59 + j*(11) -47 + j*(-105) --69 + j*(-129) --163 + j*(-31) --121 + j*(141) -97 + j*(195) -257 + j*(-18) -95 + j*(-258) --180 + j*(-167) --146 + j*(113) -137 + j*(120) -197 + j*(-177) --105 + j*(-314) --317 + j*(-47) --110 + j*(209) -154 + j*(55) -45 + j*(-206) --199 + j*(-161) --227 + j*(14) --176 + j*(76) --161 + j*(139) --66 + j*(207) -28 + j*(161) -32 + j*(127) -88 + j*(130) -134 + j*(21) -21 + j*(-32) -13 + j*(87) -168 + j*(25) -63 + j*(-192) --204 + j*(-83) --122 + j*(182) -84 + j*(126) -18 + j*(18) --4 + j*(131) -150 + j*(105) -93 + j*(-37) --3 + j*(91) -233 + j*(173) -367 + j*(-139) -78 + j*(-336) --112 + j*(-143) --4 + j*(-45) --9 + j*(-131) --103 + j*(-71) --32 + j*(-3) --30 + j*(-91) --170 + j*(-27) --76 + j*(189) -197 + j*(115) -184 + j*(-183) --89 + j*(-236) --194 + j*(-35) --69 + j*(81) -33 + j*(7) --21 + j*(-98) --161 + j*(-71) --204 + j*(107) --37 + j*(241) -161 + j*(144) -149 + j*(-46) -23 + j*(-83) --8 + j*(-36) --11 + j*(-44) --68 + j*(-16) --21 + j*(86) -132 + j*(37) -116 + j*(-173) --110 + j*(-238) --264 + j*(-83) --255 + j*(90) --177 + j*(215) --18 + j*(296) -179 + j*(214) -214 + j*(6) -68 + j*(-100) --61 + j*(-35) --76 + j*(94) -28 + j*(204) -221 + j*(187) -339 + j*(-5) -269 + j*(-218) -93 + j*(-317) --90 + j*(-290) --208 + j*(-153) --174 + j*(-4) --92 + j*(18) --100 + j*(8) --82 + j*(83) -41 + j*(72) -41 + j*(-76) --122 + j*(-94) --178 + j*(50) --107 + j*(134) --55 + j*(170) -46 + j*(211) -180 + j*(128) -154 + j*(-30) -33 + j*(-28) -62 + j*(72) -199 + j*(27) -215 + j*(-164) -37 + j*(-307) --204 + j*(-242) --288 + j*(-9) --171 + j*(158) --47 + j*(177) -31 + j*(182) -157 + j*(148) -211 + j*(-5) -117 + j*(-101) -71 + j*(-81) -66 + j*(-141) --81 + j*(-169) --163 + j*(18) -25 + j*(127) -137 + j*(-39) -8 + j*(-131) --37 + j*(-42) -28 + j*(-64) --48 + j*(-138) --127 + j*(-55) --64 + j*(-16) --105 + j*(-90) --244 + j*(19) --136 + j*(239) -115 + j*(183) -109 + j*(-37) --54 + j*(-30) --6 + j*(98) -125 + j*(0) --4 + j*(-169) --224 + j*(-39) --127 + j*(221) -142 + j*(183) -163 + j*(-52) -3 + j*(-110) --57 + j*(-47) --82 + j*(-33) --137 + j*(42) --74 + j*(148) -19 + j*(119) --8 + j*(95) -24 + j*(173) -148 + j*(144) -152 + j*(57) -177 + j*(71) -301 + j*(-57) -147 + j*(-323) --212 + j*(-216) --170 + j*(158) -158 + j*(166) -208 + j*(-74) -96 + j*(-134) -68 + j*(-169) --72 + j*(-209) --172 + j*(-21) -32 + j*(85) -112 + j*(-146) --152 + j*(-204) --201 + j*(76) -69 + j*(110) -78 + j*(-144) --173 + j*(-148) --206 + j*(94) -5 + j*(179) -146 + j*(25) -59 + j*(-169) --175 + j*(-153) --226 + j*(95) -10 + j*(196) -125 + j*(-16) --63 + j*(-127) --161 + j*(30) --50 + j*(101) --45 + j*(33) --116 + j*(107) -6 + j*(240) -213 + j*(154) -223 + j*(-80) -44 + j*(-195) --124 + j*(-118) --154 + j*(23) --95 + j*(109) --25 + j*(144) -65 + j*(130) -93 + j*(28) --23 + j*(3) --41 + j*(175) -191 + j*(228) -316 + j*(4) -185 + j*(-139) -129 + j*(-107) -139 + j*(-197) --44 + j*(-263) --156 + j*(-78) --8 + j*(11) -12 + j*(-128) --142 + j*(-95) --98 + j*(57) -14 + j*(12) --44 + j*(-38) --41 + j*(38) -37 + j*(-1) --17 + j*(-58) --8 + j*(2) -69 + j*(-117) --173 + j*(-255) --416 + j*(61) --106 + j*(380) -202 + j*(123) --37 + j*(-95) --159 + j*(194) -202 + j*(280) -305 + j*(-110) --48 + j*(-237) --175 + j*(40) -17 + j*(151) -99 + j*(49) -89 + j*(11) -108 + j*(-40) -42 + j*(-106) --22 + j*(-56) -32 + j*(-42) --19 + j*(-139) --181 + j*(-54) --98 + j*(169) -161 + j*(101) -119 + j*(-177) --168 + j*(-175) --224 + j*(81) --42 + j*(186) -69 + j*(107) -79 + j*(40) -71 + j*(-13) -8 + j*(-39) --18 + j*(30) -74 + j*(40) -71 + j*(-88) --93 + j*(-84) --103 + j*(117) -117 + j*(165) -234 + j*(-37) -115 + j*(-219) --88 + j*(-229) --228 + j*(-66) --147 + j*(160) -113 + j*(151) -153 + j*(-106) --80 + j*(-168) --131 + j*(13) --11 + j*(6) --115 + j*(-80) --220 + j*(122) -30 + j*(283) -231 + j*(51) -51 + j*(-148) --115 + j*(-27) --54 + j*(92) -1 + j*(101) -71 + j*(133) -204 + j*(47) -149 + j*(-150) --49 + j*(-141) --57 + j*(23) -74 + j*(31) -106 + j*(-79) -54 + j*(-171) --86 + j*(-245) --306 + j*(-141) --325 + j*(156) --70 + j*(288) -83 + j*(156) -46 + j*(88) -86 + j*(115) -158 + j*(23) -77 + j*(-86) --24 + j*(-36) -1 + j*(38) -54 + j*(31) -68 + j*(4) -74 + j*(-21) -71 + j*(-45) -72 + j*(-72) -45 + j*(-136) --73 + j*(-156) --146 + j*(-31) --47 + j*(54) -6 + j*(-28) --95 + j*(-40) --88 + j*(93) -56 + j*(94) -69 + j*(-23) -12 + j*(-25) -54 + j*(-30) -16 + j*(-139) --152 + j*(-108) --157 + j*(76) --4 + j*(113) -44 + j*(16) -5 + j*(-21) --18 + j*(-37) --75 + j*(-35) --98 + j*(37) --44 + j*(64) --59 + j*(38) --85 + j*(127) -62 + j*(199) -191 + j*(50) -99 + j*(-103) --20 + j*(-98) --95 + j*(-77) --221 + j*(28) --174 + j*(302) -161 + j*(393) -378 + j*(131) -269 + j*(-100) -143 + j*(-91) -175 + j*(-71) -202 + j*(-180) -83 + j*(-320) --159 + j*(-292) --243 + j*(-25) -6 + j*(103) -125 + j*(-158) --182 + j*(-278) --330 + j*(53) --28 + j*(209) -87 + j*(-44) --133 + j*(-98) --148 + j*(98) --8 + j*(100) --25 + j*(47) -15 + j*(103) -116 + j*(-4) --33 + j*(-134) --166 + j*(30) --9 + j*(145) -65 + j*(6) --54 + j*(-18) --39 + j*(66) --13 + j*(16) --127 + j*(62) --58 + j*(260) -182 + j*(251) -255 + j*(86) -262 + j*(12) -310 + j*(-136) -165 + j*(-339) --88 + j*(-323) --206 + j*(-184) --265 + j*(-32) --186 + j*(199) -124 + j*(227) -233 + j*(-72) -2 + j*(-201) --70 + j*(-66) --18 + j*(-109) --199 + j*(-134) --247 + j*(142) -52 + j*(219) -122 + j*(-47) --98 + j*(-73) --71 + j*(100) -48 + j*(25) --83 + j*(-39) --117 + j*(148) -96 + j*(191) -163 + j*(14) -69 + j*(-51) -52 + j*(-48) --1 + j*(-100) --112 + j*(-35) --72 + j*(105) -53 + j*(110) -95 + j*(47) -127 + j*(4) -151 + j*(-115) -1 + j*(-254) --248 + j*(-164) --279 + j*(143) --1 + j*(298) -228 + j*(104) -124 + j*(-119) --37 + j*(-70) -9 + j*(3) --1 + j*(-85) --151 + j*(-22) --82 + j*(185) -129 + j*(152) -133 + j*(8) -112 + j*(22) -209 + j*(-59) -104 + j*(-248) --107 + j*(-182) --71 + j*(-43) --45 + j*(-108) --172 + j*(-52) --74 + j*(115) -83 + j*(-25) --111 + j*(-149) --212 + j*(94) -50 + j*(164) -59 + j*(-96) --214 + j*(-33) --108 + j*(274) -221 + j*(184) -180 + j*(-109) --30 + j*(-104) --18 + j*(21) -74 + j*(-22) -15 + j*(-140) --161 + j*(-123) --222 + j*(91) --16 + j*(219) -119 + j*(31) --93 + j*(-53) --136 + j*(249) -267 + j*(321) -422 + j*(-106) -83 + j*(-326) --103 + j*(-133) --19 + j*(-66) --76 + j*(-122) --156 + j*(-10) --61 + j*(81) -4 + j*(31) --7 + j*(6) --9 + j*(-18) --76 + j*(-28) --103 + j*(77) -8 + j*(109) --6 + j*(26) --76 + j*(143) -158 + j*(265) -379 + j*(-24) -124 + j*(-326) --173 + j*(-161) --82 + j*(57) -29 + j*(-19) --76 + j*(-59) --96 + j*(74) -27 + j*(110) -71 + j*(33) -47 + j*(18) -88 + j*(33) -153 + j*(-46) -93 + j*(-183) --85 + j*(-192) --160 + j*(-37) --65 + j*(51) --23 + j*(8) --49 + j*(45) -68 + j*(91) -153 + j*(-83) --45 + j*(-222) --215 + j*(-39) --76 + j*(128) -57 + j*(24) --31 + j*(-62) --94 + j*(17) --35 + j*(77) -25 + j*(60) -62 + j*(13) -48 + j*(-77) --66 + j*(-117) --169 + j*(-25) --148 + j*(110) --46 + j*(175) -66 + j*(153) -118 + j*(61) -73 + j*(-13) -18 + j*(15) -72 + j*(76) -202 + j*(-4) -170 + j*(-243) --148 + j*(-337) --383 + j*(-37) --180 + j*(274) -90 + j*(170) -14 + j*(19) --11 + j*(147) -204 + j*(98) -129 + j*(-184) --167 + j*(-109) --95 + j*(139) -38 + j*(57) --108 + j*(78) -52 + j*(354) -470 + j*(147) -305 + j*(-340) --129 + j*(-233) --25 + j*(78) -165 + j*(-70) --12 + j*(-168) --20 + j*(11) -165 + j*(-69) -56 + j*(-277) --128 + j*(-223) --151 + j*(-162) --265 + j*(-139) --330 + j*(69) --180 + j*(206) --98 + j*(208) -23 + j*(308) -322 + j*(173) -234 + j*(-235) --176 + j*(-170) --61 + j*(183) -243 + j*(-21) --40 + j*(-298) --281 + j*(18) -28 + j*(190) -106 + j*(-104) --175 + j*(-97) --111 + j*(153) -73 + j*(53) --63 + j*(-48) --102 + j*(122) -65 + j*(134) -61 + j*(25) -47 + j*(66) -148 + j*(-6) -30 + j*(-163) --146 + j*(-35) --18 + j*(112) -71 + j*(-20) --81 + j*(-45) --62 + j*(141) -157 + j*(104) -135 + j*(-134) --111 + j*(-157) --197 + j*(73) --11 + j*(230) -194 + j*(111) -134 + j*(-102) --62 + j*(-59) --3 + j*(141) -239 + j*(83) -249 + j*(-192) -9 + j*(-319) --204 + j*(-199) --226 + j*(18) --57 + j*(117) -35 + j*(-24) --144 + j*(-77) --189 + j*(177) -117 + j*(246) -204 + j*(-59) --71 + j*(-129) --109 + j*(110) -74 + j*(128) -74 + j*(46) -125 + j*(105) -293 + j*(-47) -124 + j*(-316) --171 + j*(-190) --82 + j*(49) -76 + j*(-41) --20 + j*(-145) --95 + j*(-79) --88 + j*(-45) --96 + j*(4) --4 + j*(19) --30 + j*(-130) --269 + j*(-49) --153 + j*(281) -231 + j*(144) -61 + j*(-247) --316 + j*(-23) --40 + j*(334) -289 + j*(28) --18 + j*(-257) --237 + j*(28) -10 + j*(163) -55 + j*(-52) --143 + j*(-21) --86 + j*(154) -36 + j*(115) -16 + j*(90) -100 + j*(114) -154 + j*(-57) --74 + j*(-144) --199 + j*(110) -39 + j*(281) -238 + j*(115) -183 + j*(-55) -107 + j*(-86) -57 + j*(-136) --100 + j*(-133) --185 + j*(79) -18 + j*(264) -272 + j*(126) -228 + j*(-124) -57 + j*(-138) -52 + j*(-62) -74 + j*(-105) -11 + j*(-100) -70 + j*(-62) -100 + j*(-229) --173 + j*(-303) --309 + j*(14) --11 + j*(165) -88 + j*(-107) --182 + j*(-122) --108 + j*(158) -177 + j*(-9) --81 + j*(-312) --420 + j*(10) --87 + j*(375) -267 + j*(65) --15 + j*(-252) --297 + j*(1) --99 + j*(247) -85 + j*(129) -24 + j*(45) -37 + j*(105) -133 + j*(47) -86 + j*(-66) -2 + j*(-36) -59 + j*(-3) -82 + j*(-129) --110 + j*(-208) --272 + j*(-12) --133 + j*(203) -57 + j*(128) --1 + j*(5) --67 + j*(95) -56 + j*(132) -55 + j*(2) --104 + j*(74) -21 + j*(325) -397 + j*(245) -479 + j*(-168) -187 + j*(-424) --112 + j*(-354) --223 + j*(-171) --210 + j*(-34) --180 + j*(40) --151 + j*(127) --30 + j*(218) -151 + j*(151) -162 + j*(-45) --1 + j*(-98) --57 + j*(28) -45 + j*(92) -136 + j*(23) -131 + j*(-99) -6 + j*(-171) --126 + j*(-63) --30 + j*(97) -153 + j*(-6) -38 + j*(-223) --206 + j*(-115) --122 + j*(133) -104 + j*(64) -32 + j*(-139) --155 + j*(-63) --92 + j*(118) -71 + j*(85) -76 + j*(-45) -3 + j*(-83) --49 + j*(-84) --129 + j*(-49) --145 + j*(93) -30 + j*(165) -148 + j*(-16) --26 + j*(-164) --193 + j*(-4) --58 + j*(157) -66 + j*(52) --34 + j*(-5) --21 + j*(121) -144 + j*(62) -71 + j*(-129) --114 + j*(-54) --28 + j*(91) -74 + j*(-21) --74 + j*(-101) --159 + j*(49) --75 + j*(139) --42 + j*(163) -66 + j*(264) -320 + j*(168) -315 + j*(-167) -11 + j*(-255) --103 + j*(-51) -8 + j*(26) -26 + j*(-25) -5 + j*(4) -61 + j*(14) -71 + j*(-38) -62 + j*(-42) -102 + j*(-91) -30 + j*(-209) --154 + j*(-167) --170 + j*(28) --4 + j*(84) -75 + j*(-52) --42 + j*(-158) --196 + j*(-76) --167 + j*(122) -52 + j*(160) -147 + j*(-67) --71 + j*(-224) --288 + j*(-60) --233 + j*(160) --115 + j*(214) --53 + j*(279) -156 + j*(344) -403 + j*(129) -305 + j*(-223) --13 + j*(-255) --86 + j*(-47) -35 + j*(-33) --35 + j*(-149) --202 + j*(-40) --119 + j*(170) -86 + j*(138) -84 + j*(-18) --21 + j*(-8) -10 + j*(69) -79 + j*(35) -62 + j*(-9) -64 + j*(6) -117 + j*(-38) -78 + j*(-147) --62 + j*(-166) --147 + j*(-49) --96 + j*(75) -23 + j*(88) -79 + j*(8) -55 + j*(-57) -28 + j*(-82) --13 + j*(-128) --125 + j*(-137) --226 + j*(-23) --197 + j*(148) --41 + j*(251) -158 + j*(197) -228 + j*(-18) -69 + j*(-161) --68 + j*(-64) -13 + j*(20) -49 + j*(-93) --93 + j*(-119) --125 + j*(1) --74 + j*(-6) --194 + j*(5) --200 + j*(272) -164 + j*(381) -399 + j*(35) -170 + j*(-278) --124 + j*(-202) --181 + j*(1) --99 + j*(130) -40 + j*(155) -115 + j*(48) -47 + j*(-8) -49 + j*(64) -170 + j*(11) -112 + j*(-161) --74 + j*(-132) --78 + j*(27) -31 + j*(60) -92 + j*(13) -125 + j*(-69) -62 + j*(-180) --76 + j*(-174) --123 + j*(-94) --156 + j*(-50) --170 + j*(93) -50 + j*(170) -159 + j*(-115) --197 + j*(-238) --335 + j*(179) -103 + j*(320) -206 + j*(-99) --185 + j*(-123) --128 + j*(246) -194 + j*(129) -23 + j*(-105) --100 + j*(143) -235 + j*(190) -255 + j*(-187) --83 + j*(-195) --48 + j*(43) -90 + j*(-62) --66 + j*(-126) --54 + j*(26) -61 + j*(-91) --182 + j*(-188) --292 + j*(146) -59 + j*(268) -154 + j*(-42) --104 + j*(-69) --62 + j*(144) -95 + j*(56) --24 + j*(-26) --31 + j*(132) -156 + j*(95) -112 + j*(-81) --4 + j*(-31) -79 + j*(8) -69 + j*(-118) --75 + j*(-99) --64 + j*(18) --15 + j*(8) --44 + j*(33) -38 + j*(95) -130 + j*(-11) -35 + j*(-104) --21 + j*(-25) -64 + j*(-24) -41 + j*(-137) --82 + j*(-142) --141 + j*(-64) --153 + j*(28) --67 + j*(131) -93 + j*(62) -26 + j*(-125) --173 + j*(-42) --63 + j*(158) -138 + j*(8) --60 + j*(-206) --307 + j*(6) --136 + j*(267) -69 + j*(159) --29 + j*(66) --37 + j*(230) -202 + j*(243) -265 + j*(5) -98 + j*(-65) -90 + j*(48) -213 + j*(-6) -160 + j*(-149) -56 + j*(-121) -119 + j*(-106) -91 + j*(-280) --187 + j*(-302) --305 + j*(-4) --69 + j*(175) -116 + j*(18) -30 + j*(-141) --93 + j*(-135) --163 + j*(-81) --216 + j*(28) --139 + j*(171) -18 + j*(165) -49 + j*(78) -57 + j*(83) -155 + j*(21) -103 + j*(-164) --122 + j*(-168) --175 + j*(40) --28 + j*(109) -23 + j*(23) --23 + j*(6) --10 + j*(32) -2 + j*(1) --35 + j*(-1) --23 + j*(35) -13 + j*(-4) --66 + j*(-68) --210 + j*(28) --175 + j*(274) -111 + j*(379) -349 + j*(170) -293 + j*(-82) -161 + j*(-128) -151 + j*(-157) -40 + j*(-276) --187 + j*(-195) --172 + j*(47) -14 + j*(54) --13 + j*(-79) --132 + j*(-13) --64 + j*(110) -35 + j*(85) -52 + j*(49) -99 + j*(15) -79 + j*(-91) --39 + j*(-89) --27 + j*(5) -39 + j*(-52) --76 + j*(-105) --136 + j*(44) -11 + j*(106) -51 + j*(-4) --18 + j*(1) -37 + j*(23) -4 + j*(-74) --138 + j*(35) -53 + j*(249) -366 + j*(14) -157 + j*(-379) --248 + j*(-250) --188 + j*(83) -41 + j*(38) --22 + j*(-115) --141 + j*(-55) --129 + j*(31) --105 + j*(80) --28 + j*(122) -49 + j*(49) --32 + j*(-14) --62 + j*(99) -91 + j*(110) -94 + j*(-57) --52 + j*(-32) -41 + j*(77) -134 + j*(-120) --168 + j*(-247) --377 + j*(124) --13 + j*(419) -333 + j*(126) -125 + j*(-203) --144 + j*(-54) --21 + j*(157) -153 + j*(50) -77 + j*(-89) --10 + j*(-42) -33 + j*(-24) --8 + j*(-95) --121 + j*(-30) --54 + j*(96) -50 + j*(21) --81 + j*(-54) --167 + j*(165) -110 + j*(319) -340 + j*(62) -156 + j*(-168) -14 + j*(-24) -199 + j*(27) -245 + j*(-236) --26 + j*(-341) --163 + j*(-165) --98 + j*(-92) --140 + j*(-118) --202 + j*(-4) --97 + j*(97) --11 + j*(29) --64 + j*(-8) --75 + j*(61) -6 + j*(84) -62 + j*(32) -72 + j*(-46) -13 + j*(-127) --112 + j*(-111) --132 + j*(13) --25 + j*(25) --56 + j*(-96) --250 + j*(-49) --264 + j*(226) -14 + j*(361) -247 + j*(173) -189 + j*(-72) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -];