{"id":540,"date":"2026-01-25T11:09:03","date_gmt":"2026-01-25T11:09:03","guid":{"rendered":"https:\/\/demo.sans.org.sa\/?p=540"},"modified":"2026-03-26T08:19:06","modified_gmt":"2026-03-26T08:19:06","slug":"pituitary-adenoma-intensive-course","status":"publish","type":"post","link":"https:\/\/sans.org.sa\/sans2026\/pituitary-adenoma-intensive-course\/","title":{"rendered":"Pituitary Adenoma Intensive Course"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"540\" class=\"elementor elementor-540\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-339b1308 elementor-section-height-min-height eael_liquid_glass-effect2 elementor-section-boxed elementor-section-height-default elementor-section-items-middle\" data-id=\"339b1308\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-6fdf83fe\" data-id=\"6fdf83fe\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-1d9eda01 elementor-invisible elementor-widget elementor-widget-heading\" data-id=\"1d9eda01\" data-element_type=\"widget\" data-settings=\"{&quot;_animation&quot;:&quot;fadeIn&quot;,&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Pituitary Adenoma Intensive Course<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1ecca85 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"1ecca85\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-cfb9f81 elementor-invisible\" data-id=\"cfb9f81\" data-element_type=\"column\" data-settings=\"{&quot;animation&quot;:&quot;fadeInUp&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-b7d6c84 elementor-widget elementor-widget-shortcode\" data-id=\"b7d6c84\" data-element_type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div class=\"_df_book df-lite\" id=\"df_928\"  _slug=\"pituitary-adenoma-workshop\" data-title=\"pituitary-adenoma-workshop\" wpoptions=\"true\" thumbtype=\"\" ><\/div><script class=\"df-shortcode-script\" nowprocket type=\"application\/javascript\">window.option_df_928 = {\"webgl\":\"false\",\"outline\":[],\"backgroundColor\":\"#08C5CE00\",\"autoEnableOutline\":\"false\",\"autoEnableThumbnail\":\"false\",\"overwritePDFOutline\":\"false\",\"direction\":\"1\",\"pageSize\":\"0\",\"source\":\"https:\\\/\\\/sans.org.sa\\\/sans2026\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/SANS-2026-Pituitary-Adenoma-Intensive-Course-Booklet-1_compressed.pdf\",\"wpOptions\":\"true\"}; if(window.DFLIP && window.DFLIP.parseBooks){window.DFLIP.parseBooks();}<\/script><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-2ee05e6f elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"2ee05e6f\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-74b2cf98\" data-id=\"74b2cf98\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-42a0487d elementor-widget elementor-widget-shortcode\" data-id=\"42a0487d\" data-element_type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div id=\"threewp-container\" style=\"display: none;\"><\/div><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3748d956 elementor-widget elementor-widget-html\" data-id=\"3748d956\" data-element_type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- THREE.JS BG NO SECTION OFFSET -->\r\n<div id=\"canvas-container\" style=\"width: 100%; height: 100vh; position: fixed; top: 0; left: 0; overflow: hidden; z-index: -1;\">\r\n    <canvas id=\"cubeCanvas\" style=\"width: 100%; height: 100%; \"><\/canvas>\r\n\r\n<\/div>\r\n\r\n<!-- Three.js core scripts -->\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/build\/three.min.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/loaders\/GLTFLoader.js\"><\/script>\r\n\r\n<!-- Postprocessing scripts -->\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/EffectComposer.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/RenderPass.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/UnrealBloomPass.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/shaders\/CopyShader.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/shaders\/LuminosityHighPassShader.js\"><\/script>\r\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/ShaderPass.js\"><\/script>\r\n\r\n\r\n<script type=\"module\">\r\n  import { MeshSurfaceSampler } from 'https:\/\/cdn.jsdelivr.net\/npm\/three-full@28.0.2\/sources\/math\/MeshSurfaceSampler.js';\r\n\r\n  \/\/ MODIFY\r\n  const MODEL_URL = 'https:\/\/sans.org.sa\/sans2026\/wp-content\/uploads\/2026\/01\/source.glb';\r\n  const PARTICLE_URL = 'https:\/\/sans.org.sa\/sans2026\/wp-content\/uploads\/2026\/01\/smoke.png';\r\n\r\n  \/\/ Particle parameters\r\n  const PARTICLE_RATE = 1000.0;\r\n  const PARTICLE_COLOR = 0x8080ff;\r\n  const TRAIL_COUNT = 5;\r\n  const TRAIL_DIST = 0.05;\r\n\r\n  \/\/ Model parameters\r\n  const INITIAL_SCALE = 1.9;\r\n  const MODEL_COLOR = 0x055d5e; \/\/0x8080ff, 0x063859, 0x9c9cff\r\n  const MODEL_INITIAL_OFFSET_Y = -1.4;\r\n  const MODEL_FINAL_OFFSET_Y = 2;\r\n  const DOT_SIZE = 0.01; \/\/ 0.005\r\n  const MAX_LINEAR_SCALE = 1.005;\r\n  const GRADUAL_SCALE_RATE = 0.025;\r\n    \r\n  \/\/ Camera\r\n  const ROTATION_SPEED = 0.005;\r\n  const CAMERA_FOV = 55;\r\n  const CAMERA_NEAR = 0.1;\r\n  const CAMERA_FAR = 3000;\r\n  const CAMERA_DISTANCE_FACTOR_DESKTOP = 5;\r\n  const CAMERA_DISTANCE_FACTOR_MOBILE = 5;\r\n  let CAMERA_OFFSET_X = 0;\r\n  let CAMERA_OFFSET_Y = 0;\r\n\r\n  \/\/ Bloom effect variables\r\n  const BLOOM_INTENSITY = 3;\r\n  const BLOOM_THRESHOLD = 0.4;\r\n  const BLOOM_RADIUS = 0.65;\r\n\r\n  \/\/ Updated light settings\r\n  const DIRECTIONAL_LIGHT_COLOR = 0xffffff;\r\n  const DIRECTIONAL_LIGHT_INTENSITY = 2;\r\n  const AMBIENT_LIGHT_COLOR = 0xffffff;\r\n  const AMBIENT_LIGHT_INTENSITY = 10;\/\/1\r\n  const ADDITIONAL_LIGHT_COLOR = 0xffffff;\r\n  const ADDITIONAL_LIGHT_INTENSITY = 2;\r\n\r\n  \/\/ background colour settings\r\n  const BACKGROUND_COLOUR_SCENE = 0x000000; \/\/ White background\r\n  const BACKGROUND_COLOUR_TRANSPARENCE = 0; \/\/ Fully opaque\r\n\r\n\/\/----------------\r\n\/\/ End of controls\r\n\/\/----------------\r\n\r\n\/\/---------------------\r\n\/\/ GETPARTICLESYSTEM JS\r\n\/\/---------------------\r\n  let updateParticles = true;\r\n  const _VS = `\r\n  uniform float pointMultiplier;\r\n\r\n  attribute float size;\r\n  attribute float angle;\r\n  attribute vec4 aColor;\r\n\r\n  varying vec4 vColor;\r\n  varying vec2 vAngle;\r\n\r\n  void main() {\r\n    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\r\n\r\n    gl_Position = projectionMatrix * mvPosition;\r\n    gl_PointSize = size * pointMultiplier \/ gl_Position.w;\r\n\r\n    vAngle = vec2(cos(angle), sin(angle));\r\n    vColor = aColor;\r\n  }`;\r\n\r\n  const _FS = `\r\n  uniform sampler2D diffuseTexture;\r\n\r\n  varying vec4 vColor;\r\n  varying vec2 vAngle;\r\n\r\n  void main() {\r\n    vec2 coords = (gl_PointCoord - 0.5) * mat2(vAngle.x, vAngle.y, -vAngle.y, vAngle.x) + 0.5;\r\n    gl_FragColor = texture2D(diffuseTexture, coords) * vColor;\r\n  }`;\r\n\r\n\r\n  function getLinearSpline(lerp) {\r\n\r\n    const points = [];\r\n    const _lerp = lerp;\r\n\r\n    function addPoint(t, d) {\r\n      points.push([t, d]);\r\n    }\r\n\r\n    function getValueAt(t) {\r\n      let p1 = 0;\r\n\r\n      for (let i = 0; i < points.length; i++) {\r\n        if (points[i][0] >= t) {\r\n          break;\r\n        }\r\n        p1 = i;\r\n      }\r\n\r\n      const p2 = Math.min(points.length - 1, p1 + 1);\r\n\r\n      if (p1 == p2) {\r\n        return points[p1][1];\r\n      }\r\n\r\n      return _lerp(\r\n        (t - points[p1][0]) \/ (\r\n          points[p2][0] - points[p1][0]),\r\n        points[p1][1], points[p2][1]);\r\n    }\r\n    return { addPoint, getValueAt };\r\n  }\r\n      \r\n  function getParticleSystem(params) {\r\n    const { camera, emitter, parent, rate, texture } = params;\r\n    let sampler = new MeshSurfaceSampler(emitter).build();\r\n\r\n    const uniforms = {\r\n      diffuseTexture: {\r\n        value: new THREE.TextureLoader().load(texture)\r\n      },\r\n      pointMultiplier: {\r\n        value: window.innerHeight \/ (2.0 * Math.tan(30.0 * Math.PI \/ 180.0))\r\n      }\r\n    };\r\n\r\n    const _material = new THREE.ShaderMaterial({\r\n      uniforms: uniforms,\r\n      vertexShader: _VS,\r\n      fragmentShader: _FS,\r\n      blending: THREE.AdditiveBlending,\r\n      depthTest: true,\r\n      depthWrite: false,\r\n      transparent: true,\r\n      vertexColors: true\r\n    });\r\n\r\n    let _particles = [];\r\n\r\n    const geometry = new THREE.BufferGeometry();\r\n    geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));\r\n    geometry.setAttribute('size', new THREE.Float32BufferAttribute([], 1));\r\n    geometry.setAttribute('aColor', new THREE.Float32BufferAttribute([], 4));\r\n    geometry.setAttribute('angle', new THREE.Float32BufferAttribute([], 1));\r\n\r\n    const _points = new THREE.Points(geometry, _material);\r\n\r\n    parent.add(_points);\r\n\r\n    const alphaSpline = getLinearSpline((t, a, b) => {\r\n      return a + t * (b - a);\r\n    });\r\n    alphaSpline.addPoint(0.0, 0.0);\r\n    alphaSpline.addPoint(0.6, 1.0);\r\n    alphaSpline.addPoint(1.0, 0.0);\r\n\r\n    const colorSpline = getLinearSpline((t, a, b) => {\r\n      const c = a.clone();\r\n      return c.lerp(b, t);\r\n    });\r\n    colorSpline.addPoint(0.0, new THREE.Color(0xFFFFFF));\r\n    colorSpline.addPoint(1.0, new THREE.Color(PARTICLE_COLOR));\r\n\r\n    const sizeSpline = getLinearSpline((t, a, b) => {\r\n      return a + t * (b - a);\r\n    });\r\n    sizeSpline.addPoint(0.0, 0.0);\r\n    sizeSpline.addPoint(1.0, 1.0);\r\n  \/\/ max point size = 512; => console.log(ctx.getParameter(ctx.ALIASED_POINT_SIZE_RANGE));\r\n    const maxLife = 1.5;\r\n    const maxSize = 0.08;\/\/.15\r\n    let gdfsghk = 0.0;\r\n\r\n    function _AddParticles(timeElapsed) {\r\n      if (!updateParticles) return;\r\n      let radius = objGroup.scale.x * INITIAL_SCALE;\r\n      let y_offset = objGroup.position.y;\r\n\r\n      gdfsghk += timeElapsed;\r\n      const n = Math.floor(gdfsghk * rate);\r\n      gdfsghk -= n \/ rate;\r\n      \r\n      for (let i = 0; i < n; i += 1) {\r\n        const life = (Math.random() * 0.75 + 0.25) * maxLife;\r\n        \r\n        \r\n        const pos = new THREE.Vector3();\r\n        sampler.sample(pos, pos);\r\n\r\n        const direction = Math.random() * 2.0 * Math.PI;\r\n\r\n        \/\/ Add trailing points\r\n        for (let j = 0; j < TRAIL_COUNT; j +=1 ) {\r\n          _particles.push({\r\n\r\n            \/\/ Initial Position\r\n            position: new THREE.Vector3(\r\n              pos.x*radius,\r\n              (pos.y*radius)-(j*TRAIL_DIST) + y_offset,\r\n              pos.z*radius\r\n            ),\r\n\r\n            size: (Math.random() * 0.5 + 0.5) * maxSize,\r\n            colour: new THREE.Color(),\r\n            alpha: 1.0,\r\n            life: life,\r\n            maxLife: life,\r\n            rotation: direction,\r\n            rotationRate: Math.random() * 0.01 - 0.005,\r\n            velocity: new THREE.Vector3(0, .75, 0),\/\/1.5\r\n          });\r\n        }\r\n\r\n      }\r\n    }\r\n\r\n    function _UpdateGeometry() {\r\n      const positions = [];\r\n      const sizes = [];\r\n      const colours = [];\r\n      const angles = [];\r\n\r\n      for (let p of _particles) {\r\n        positions.push(p.position.x, p.position.y, p.position.z);\r\n        colours.push(p.colour.r, p.colour.g, p.colour.b, p.alpha);\r\n        sizes.push(p.currentSize);\r\n        angles.push(p.rotation);\r\n      }\r\n\r\n      geometry.setAttribute(\r\n        'position', new THREE.Float32BufferAttribute(positions, 3));\r\n      geometry.setAttribute(\r\n        'size', new THREE.Float32BufferAttribute(sizes, 1));\r\n      geometry.setAttribute(\r\n        'aColor', new THREE.Float32BufferAttribute(colours, 4));\r\n      geometry.setAttribute(\r\n        'angle', new THREE.Float32BufferAttribute(angles, 1));\r\n\r\n      geometry.attributes.position.needsUpdate = true;\r\n      geometry.attributes.size.needsUpdate = true;\r\n      geometry.attributes.aColor.needsUpdate = true;\r\n      geometry.attributes.angle.needsUpdate = true;\r\n    }\r\n    _UpdateGeometry();\r\n\r\n    function _UpdateParticles(timeElapsed) {\r\n      for (let p of _particles) {\r\n        p.life -= timeElapsed;\r\n      }\r\n\r\n      _particles = _particles.filter(p => {\r\n        return p.life > 0.0;\r\n      });\r\n\r\n      for (let p of _particles) {\r\n        const t = 1.0 - p.life \/ p.maxLife;\r\n        p.rotation += p.rotationRate;\r\n        p.alpha = alphaSpline.getValueAt(t);\r\n        p.currentSize = p.size * sizeSpline.getValueAt(t);\r\n        p.colour.copy(colorSpline.getValueAt(t));\r\n\r\n        p.position.add(p.velocity.clone().multiplyScalar(timeElapsed));\r\n\r\n        const drag = p.velocity.clone();\r\n        drag.multiplyScalar(timeElapsed * 0.1);\r\n        drag.x = Math.sign(p.velocity.x) * Math.min(Math.abs(drag.x), Math.abs(p.velocity.x));\r\n        drag.y = Math.sign(p.velocity.y) * Math.min(Math.abs(drag.y), Math.abs(p.velocity.y));\r\n        drag.z = Math.sign(p.velocity.z) * Math.min(Math.abs(drag.z), Math.abs(p.velocity.z));\r\n        p.velocity.sub(drag);\r\n      }\r\n\r\n      _particles.sort((a, b) => {\r\n        const d1 = camera.position.distanceTo(a.position);\r\n        const d2 = camera.position.distanceTo(b.position);\r\n\r\n        if (d1 > d2) {\r\n          return -1;\r\n        }\r\n        if (d1 < d2) {\r\n          return 1;\r\n        }\r\n        return 0;\r\n      });\r\n    }\r\n\r\n    function update(timeElapsed) {\r\n      _AddParticles(timeElapsed);\r\n      _UpdateParticles(timeElapsed);\r\n      _UpdateGeometry();\r\n    }\r\n    return { update };\r\n  }\r\n\r\n\/\/-------------\r\n\/\/ THREEJS MAIN\r\n\/\/-------------\r\n\r\n  let canvas, renderer, scene, camera, light, ambientLight, additionalLight;\r\n  let model, objGroup, camGroup, mixer, clock, composer, smokeEffect, scrollPercent;\r\n\r\n  const pointMaterial = new THREE.PointsMaterial({\r\n    color: MODEL_COLOR,\r\n    size: DOT_SIZE,\r\n    transparent: true,\r\n    opacity: 0,\r\n    sizeAttenuation: true\r\n  })\r\n\r\n  function setupScene() {\r\n    canvas = document.getElementById('cubeCanvas');\r\n    renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: false, antialias: true });\r\n    renderer.setClearColor(BACKGROUND_COLOUR_SCENE, BACKGROUND_COLOUR_TRANSPARENCE);\r\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\r\n\r\n    scene = new THREE.Scene();\r\n    scene.background = new THREE.Color(BACKGROUND_COLOUR_SCENE);\r\n    camera = new THREE.PerspectiveCamera(CAMERA_FOV, canvas.clientWidth \/ canvas.clientHeight, CAMERA_NEAR, CAMERA_FAR);\r\n    camGroup = new THREE.Group();\r\n    camGroup.add(camera);\r\n\r\n    \/\/ Use updated light settings\r\n    ambientLight = new THREE.AmbientLight(AMBIENT_LIGHT_COLOR, AMBIENT_LIGHT_INTENSITY);\r\n    scene.add(ambientLight);\r\n\r\n    light = new THREE.DirectionalLight(DIRECTIONAL_LIGHT_COLOR, DIRECTIONAL_LIGHT_INTENSITY);\r\n    light.position.set(10, 10, 10).normalize();\r\n    scene.add(light);\r\n\r\n    additionalLight = new THREE.PointLight(ADDITIONAL_LIGHT_COLOR, ADDITIONAL_LIGHT_INTENSITY, 100);\r\n    additionalLight.position.set(-15, 0, -15);\r\n    scene.add(additionalLight);\r\n\r\n    objGroup = new THREE.Group();\r\n    scene.add(objGroup);\r\n\r\n    clock = new THREE.Clock();\r\n\r\n    \/\/ Postprocessing setup\r\n    composer = new THREE.EffectComposer(renderer);\r\n    const renderPass = new THREE.RenderPass(scene, camera);\r\n    renderPass.clearColor = new THREE.Color(BACKGROUND_COLOUR_SCENE);\r\n    renderPass.clearAlpha = BACKGROUND_COLOUR_TRANSPARENCE;\r\n    composer.addPass(renderPass);\r\n\r\n    const bloomPass = new THREE.UnrealBloomPass(\r\n        new THREE.Vector2(window.innerWidth \/ 2, window.innerHeight \/ 2), \/\/ Reduced resolution\r\n        BLOOM_INTENSITY,\r\n        BLOOM_THRESHOLD,\r\n        BLOOM_RADIUS\r\n    );\r\n    composer.addPass(bloomPass);\r\n\r\n    resizeCanvas();\r\n  }\r\n\r\n  function fitModelToCanvas() {\r\n    if (!model) return;\r\n\r\n    const box = new THREE.Box3().setFromObject(model);\r\n    const center = box.getCenter(new THREE.Vector3());\r\n\r\n    model.position.sub(center);\r\n\r\n    const isMobile = window.innerWidth <= 768;\r\n    let distance = isMobile ? CAMERA_DISTANCE_FACTOR_MOBILE : CAMERA_DISTANCE_FACTOR_DESKTOP;\r\n\r\n    camera.position.set(CAMERA_OFFSET_X, CAMERA_OFFSET_Y, distance);\r\n    camera.lookAt(new THREE.Vector3(0, 0, 0));\r\n    camera.updateProjectionMatrix();\r\n  \r\n    renderer.setSize(canvas.clientWidth, canvas.clientHeight);\r\n  }\r\n\r\n  function animate() {\r\n    requestAnimationFrame(animate);\r\n\r\n    if (mixer) {\r\n      mixer.update(clock.getDelta());\r\n    }\r\n    if (pointMaterial.opacity < 1) pointMaterial.opacity += 0.005;\r\n\r\n    smokeEffect.update(0.016);\r\n\r\n    camGroup.rotation.y += ROTATION_SPEED;\r\n\r\n    camera.lookAt(new THREE.Vector3(0, 0, 0));\r\n    composer.render();\r\n  }\r\n\r\n  function resizeCanvas() {\r\n    \/*if ((canvas && renderer && camera)) {*\/\r\n      camera.aspect = canvas.clientWidth \/ canvas.clientHeight;\r\n      camera.updateProjectionMatrix();\r\n      renderer.setSize(canvas.clientWidth, canvas.clientHeight);\r\n      composer.setSize(canvas.clientWidth, canvas.clientHeight);\r\n      if (model) {\r\n        fitModelToCanvas();\r\n      }\r\n    \/\/}\r\n  }\r\n\r\n  function updateLoadingScreen(progress) {\r\n    const progressText = document.getElementById('loading-progress');\r\n    if (progressText) {\r\n        progressText.textContent = `Loading 3D Model: ${Math.round(progress * 100)}%`;\r\n    }\r\n  }\r\n\r\n  function hideLoadingScreen() {\r\n      const loadingScreen = document.getElementById('loading-screen');\r\n      if (loadingScreen) {\r\n          loadingScreen.style.display = 'none';\r\n      }\r\n  }\r\n\r\n  function startModelLoad() {\r\n    const loadingManager = new THREE.LoadingManager();\r\n\r\n    loadingManager.onProgress = function (url, itemsLoaded, itemsTotal) {\r\n      updateLoadingScreen(itemsLoaded \/ itemsTotal);\r\n    };\r\n\r\n    loadingManager.onLoad = function () {\r\n      hideLoadingScreen();\r\n    };\r\n\r\n    const loader = new THREE.GLTFLoader(loadingManager);\r\n\r\n    loader.load(MODEL_URL,\r\n      function (gltf) {\r\n        model = gltf.scene;\r\n              \r\n        model.traverse((mesh) => {\r\n          if (mesh.isMesh) {\r\n            \r\n\r\n            let points = new THREE.Points(mesh.geometry, pointMaterial);\r\n            points.rotation.copy(mesh.rotation);\r\n            points.rotation.x = -90 * (Math.PI\/180);\r\n            points.scale.set(INITIAL_SCALE, INITIAL_SCALE, INITIAL_SCALE);\r\n            model = points;\r\n\r\n            model.position.set(0, 0, 0);\r\n          }\r\n        }) \r\n\r\n        objGroup.add(model);\r\n        fitModelToCanvas();\r\n\r\n        if (gltf.animations && gltf.animations.length) {\r\n            mixer = new THREE.AnimationMixer(model);\r\n            const animation = gltf.animations[0];\r\n            const action = mixer.clipAction(animation);\r\n            action.play();\r\n        }\r\n\r\n        smokeEffect = getParticleSystem({\r\n          camera,\r\n          emitter: model,\r\n          parent: scene,\r\n          rate: PARTICLE_RATE,\r\n          texture: PARTICLE_URL,\r\n        })\r\n\r\n        scrollPercent = window.scrollY \/ (document.documentElement.scrollHeight - window.innerHeight);\r\n        const position = (MODEL_FINAL_OFFSET_Y * scrollPercent) + MODEL_INITIAL_OFFSET_Y;\r\n        objGroup.position.y = position;\r\n\r\n        animate();\r\n      },\r\n      function (xhr) {\r\n          \/\/ Progress callback\r\n      },\r\n      function (error) {\r\n          \/\/ Error callback\r\n      }\r\n    );\r\n  }\r\n\r\n  function onScroll() {\r\n    if (model) {\r\n      scrollPercent = window.scrollY \/ (document.documentElement.scrollHeight - window.innerHeight);\r\n\r\n      \/\/ Scale\r\n      const scale = 1 + (scrollPercent * 10);\r\n      if (scale <= 1) objGroup.scale.set(1, 1, 1)\r\n      else if (scale < MAX_LINEAR_SCALE) objGroup.scale.set(scale, scale, scale);\r\n      else if (scale >= MAX_LINEAR_SCALE) {\r\n        const gradualScale = MAX_LINEAR_SCALE + ((scale-MAX_LINEAR_SCALE)*GRADUAL_SCALE_RATE);\r\n        objGroup.scale.set(gradualScale, gradualScale, gradualScale);\r\n      }\r\n\r\n      \/\/ Position \r\n      const position = (MODEL_FINAL_OFFSET_Y * scrollPercent) + MODEL_INITIAL_OFFSET_Y;\r\n      objGroup.position.y = position;\r\n    }\r\n  }\r\n\r\n  function initiateBackgroundLoading() {\r\n    setupScene();\r\n    startModelLoad();\r\n  }\r\n\r\n  initiateBackgroundLoading();\r\n  window.addEventListener('resize', resizeCanvas);\r\n\r\n  \/\/ Use requestAnimationFrame for smoother scrolling\r\n  let ticking = false;\r\n  window.addEventListener('scroll', function() {\r\n    if (!ticking) {\r\n      window.requestAnimationFrame(function() {\r\n        onScroll();\r\n        ticking = false;\r\n      });\r\n      ticking = true;\r\n    }\r\n  });\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Pituitary Adenoma Intensive Course<\/p>\n","protected":false},"author":1,"featured_media":958,"comment_status":"closed","ping_status":"open","sticky":false,"template":"elementor_header_footer","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-540","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-workshops"],"_links":{"self":[{"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/posts\/540","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/comments?post=540"}],"version-history":[{"count":39,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/posts\/540\/revisions"}],"predecessor-version":[{"id":961,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/posts\/540\/revisions\/961"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/media\/958"}],"wp:attachment":[{"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/media?parent=540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/categories?post=540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sans.org.sa\/sans2026\/wp-json\/wp\/v2\/tags?post=540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}