diff --git a/ChatGPT Image 20. Apr. 2025, 09_02_47.png b/ChatGPT Image 20. Apr. 2025, 09_02_47.png
new file mode 100644
index 0000000..c87515b
Binary files /dev/null and b/ChatGPT Image 20. Apr. 2025, 09_02_47.png differ
diff --git a/website/static/css/neural-network-background.css b/website/static/css/neural-network-background.css
new file mode 100644
index 0000000..593add5
--- /dev/null
+++ b/website/static/css/neural-network-background.css
@@ -0,0 +1,47 @@
+/* Neural Network Background CSS */
+
+/* Make sure the neural network background is always visible */
+#neural-network-background {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ width: 100% !important;
+ height: 100% !important;
+ z-index: -10 !important; /* Below content but above regular background */
+ pointer-events: none !important;
+ opacity: 1 !important;
+}
+
+/* Override any solid background colors for the body */
+body, body.dark {
+ background-color: transparent !important;
+}
+
+/* Make sure any background color is removed */
+html.dark, html {
+ background-color: transparent !important;
+}
+
+/* Make sure any fixed backgrounds are removed */
+#app-container {
+ background-color: transparent !important;
+}
+
+/* Ensure content is properly visible over the background */
+.glass-morphism {
+ background-color: rgba(17, 24, 39, 0.6) !important;
+ backdrop-filter: blur(5px) !important;
+}
+
+body.dark .glass-navbar-dark {
+ background-color: rgba(10, 14, 25, 0.7) !important;
+}
+
+body .glass-navbar-light {
+ background-color: rgba(255, 255, 255, 0.7) !important;
+}
+
+/* Make sure footer has proper transparency */
+footer {
+ background-color: rgba(10, 14, 25, 0.7) !important;
+}
\ No newline at end of file
diff --git a/website/static/neural-network-background.js b/website/static/neural-network-background.js
index a8abd2e..103b43e 100644
--- a/website/static/neural-network-background.js
+++ b/website/static/neural-network-background.js
@@ -1,6 +1,7 @@
/**
* Neural Network Background Animation
* Modern, darker, mystical theme using WebGL
+ * Subtle flowing network aesthetic
*/
class NeuralNetworkBackground {
@@ -13,11 +14,22 @@ class NeuralNetworkBackground {
this.canvas.style.left = '0';
this.canvas.style.width = '100%';
this.canvas.style.height = '100%';
- this.canvas.style.zIndex = '-5';
+ this.canvas.style.zIndex = '-10'; // Ensure it's behind content but visible
this.canvas.style.pointerEvents = 'none';
+ this.canvas.style.opacity = '1'; // Force visibility
- // Append to body
- document.body.appendChild(this.canvas);
+ // If canvas already exists, remove it first
+ const existingCanvas = document.getElementById('neural-network-background');
+ if (existingCanvas) {
+ existingCanvas.remove();
+ }
+
+ // Append to body as first child to ensure it's behind everything
+ if (document.body.firstChild) {
+ document.body.insertBefore(this.canvas, document.body.firstChild);
+ } else {
+ document.body.appendChild(this.canvas);
+ }
// WebGL context
this.gl = this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl');
@@ -33,16 +45,17 @@ class NeuralNetworkBackground {
// Animation properties
this.nodes = [];
this.connections = [];
+ this.flows = []; // Flow animations along connections
this.animationFrameId = null;
- this.isDarkMode = document.documentElement.classList.contains('dark');
+ this.isDarkMode = true; // Always use dark mode for the background
- // Colors - using hex values for better control
+ // Colors - Updated to be more subtle
this.darkModeColors = {
- background: '#0a0e19',
- nodeColor: '#6d28d9',
- nodePulse: '#8b5cf6',
- connectionColor: '#4c1d95',
- glowColor: '#7c3aed'
+ background: '#050a14', // Darker blue-black background
+ nodeColor: '#4a5568', // Darker nodes for subtlety
+ nodePulse: '#718096', // Subtle blue pulse
+ connectionColor: '#2d3748', // Darker connections
+ flowColor: '#4a88ff80' // Semi-transparent flow highlight
};
this.lightModeColors = {
@@ -50,18 +63,21 @@ class NeuralNetworkBackground {
nodeColor: '#7c3aed',
nodePulse: '#8b5cf6',
connectionColor: '#a78bfa',
- glowColor: '#c4b5fd'
+ flowColor: '#c4b5fd'
};
- // Config
+ // Config - Updated to be more flowing and subtle
this.config = {
- nodeCount: 100,
- nodeSize: 2,
- nodeVariation: 1.5,
- connectionDistance: 150,
- connectionOpacity: 0.2,
- animationSpeed: 0.3,
- pulseSpeed: 0.02
+ nodeCount: 100, // Slightly fewer nodes for cleaner look
+ nodeSize: 0.8, // Smaller nodes
+ nodeVariation: 0.5, // Less variation for uniformity
+ connectionDistance: 200, // Longer connections for better flow
+ connectionOpacity: 0.2, // More subtle connections
+ animationSpeed: 0.08, // Much slower movement
+ pulseSpeed: 0.004, // Slower pulse
+ flowSpeed: 0.6, // Speed of flow animations
+ flowDensity: 0.001, // How often new flows start (lower = less frequent)
+ flowLength: 0.2 // Length of the flow (percentage of the connection)
};
// Initialize
@@ -72,6 +88,9 @@ class NeuralNetworkBackground {
document.addEventListener('darkModeToggled', (event) => {
this.isDarkMode = event.detail.isDark;
});
+
+ // Log that the background is initialized
+ console.log('Neural Network Background initialized');
}
init() {
@@ -127,7 +146,7 @@ class NeuralNetworkBackground {
}
`;
- // Fragment shader
+ // Fragment shader - Softer glow effect
const fsSource = `
precision mediump float;
uniform vec4 uColor;
@@ -135,13 +154,9 @@ class NeuralNetworkBackground {
void main() {
float distance = length(gl_PointCoord - vec2(0.5, 0.5));
- // Soft circle with glow
- float alpha = 1.0 - smoothstep(0.3, 0.5, distance);
-
- // Add glow
- if (distance > 0.3) {
- alpha *= 0.7;
- }
+ // Softer glow with smoother falloff
+ float alpha = 1.0 - smoothstep(0.1, 0.5, distance);
+ alpha = pow(alpha, 1.5); // Make the glow even softer
gl_FragColor = vec4(uColor.rgb, uColor.a * alpha);
}
@@ -181,9 +196,7 @@ class NeuralNetworkBackground {
this.sizeBuffer = this.gl.createBuffer();
// Set clear color for WebGL context
- const bgColor = this.isDarkMode
- ? this.hexToRgb(this.darkModeColors.background)
- : this.hexToRgb(this.lightModeColors.background);
+ const bgColor = this.hexToRgb(this.darkModeColors.background);
this.gl.clearColor(bgColor.r/255, bgColor.g/255, bgColor.b/255, 1.0);
}
@@ -195,7 +208,7 @@ class NeuralNetworkBackground {
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ' +
- this.gl.getShaderInfoLog(shader));
+ this.gl.getShaderInfoLog(shader));
this.gl.deleteShader(shader);
return null;
}
@@ -228,6 +241,7 @@ class NeuralNetworkBackground {
createConnections() {
this.connections = [];
+ this.flows = []; // Reset flows
// Create connections between nearby nodes
for (let i = 0; i < this.nodes.length; i++) {
@@ -246,7 +260,8 @@ class NeuralNetworkBackground {
from: i,
to: j,
distance: distance,
- opacity: Math.max(0, 1 - distance / this.config.connectionDistance) * this.config.connectionOpacity
+ opacity: Math.max(0, 1 - distance / this.config.connectionDistance) * this.config.connectionOpacity,
+ hasFlow: false // Each connection can have a flow
};
this.connections.push(connection);
@@ -266,22 +281,34 @@ class NeuralNetworkBackground {
const width = this.canvas.width / (window.devicePixelRatio || 1);
const height = this.canvas.height / (window.devicePixelRatio || 1);
- // Update node positions
+ // Update node positions - slower, more flowing movement
for (let i = 0; i < this.nodes.length; i++) {
const node = this.nodes[i];
+ // Move node with slight randomness for organic feel
+ node.speed.x += (Math.random() - 0.5) * 0.001;
+ node.speed.y += (Math.random() - 0.5) * 0.001;
+
+ // Dampen speeds for stability
+ node.speed.x *= 0.99;
+ node.speed.y *= 0.99;
+
+ // Apply speed limits
+ node.speed.x = Math.max(-this.config.animationSpeed, Math.min(this.config.animationSpeed, node.speed.x));
+ node.speed.y = Math.max(-this.config.animationSpeed, Math.min(this.config.animationSpeed, node.speed.y));
+
// Move node
node.x += node.speed.x;
node.y += node.speed.y;
- // Boundary check with bounce
+ // Boundary check with smooth bounce
if (node.x < 0 || node.x > width) {
- node.speed.x *= -1;
+ node.speed.x *= -0.8; // Softer bounce
node.x = Math.max(0, Math.min(node.x, width));
}
if (node.y < 0 || node.y > height) {
- node.speed.y *= -1;
+ node.speed.y *= -0.8; // Softer bounce
node.y = Math.max(0, Math.min(node.y, height));
}
@@ -292,8 +319,16 @@ class NeuralNetworkBackground {
}
}
- // Recalculate connections dynamically
- if (Math.random() < 0.05) { // Only recalculate 5% of the time for performance
+ // Update flows
+ this.updateFlows();
+
+ // Occasionally create new flows along connections
+ if (Math.random() < this.config.flowDensity) {
+ this.createNewFlow();
+ }
+
+ // Recalculate connections occasionally for a living network
+ if (Math.random() < 0.01) { // Only recalculate 1% of the time for performance
this.createConnections();
}
@@ -308,6 +343,52 @@ class NeuralNetworkBackground {
this.animationFrameId = requestAnimationFrame(this.animate.bind(this));
}
+ // New method to update flow animations
+ updateFlows() {
+ // Update existing flows
+ for (let i = this.flows.length - 1; i >= 0; i--) {
+ const flow = this.flows[i];
+ flow.progress += this.config.flowSpeed / flow.connection.distance;
+
+ // Remove completed flows
+ if (flow.progress > 1.0) {
+ this.flows.splice(i, 1);
+ }
+ }
+ }
+
+ // New method to create flow animations
+ createNewFlow() {
+ if (this.connections.length === 0) return;
+
+ // Select a random connection with preference for more connected nodes
+ let connectionIdx = Math.floor(Math.random() * this.connections.length);
+ let attempts = 0;
+
+ // Try to find a connection with more connected nodes
+ while (attempts < 5) {
+ const testIdx = Math.floor(Math.random() * this.connections.length);
+ const testConn = this.connections[testIdx];
+ const fromNode = this.nodes[testConn.from];
+
+ if (fromNode.connections.length > 2) {
+ connectionIdx = testIdx;
+ break;
+ }
+ attempts++;
+ }
+
+ const connection = this.connections[connectionIdx];
+
+ // Create a new flow along this connection
+ this.flows.push({
+ connection: connection,
+ progress: 0,
+ direction: Math.random() > 0.5, // Randomly decide direction
+ length: this.config.flowLength + Math.random() * 0.1 // Slightly vary lengths
+ });
+ }
+
renderWebGL() {
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
@@ -320,9 +401,12 @@ class NeuralNetworkBackground {
// Set resolution uniform
this.gl.uniform2f(this.programInfo.uniformLocations.resolution, width, height);
- // Draw connections
+ // Draw connections first (behind nodes)
this.renderConnectionsWebGL();
+ // Draw flows on top of connections
+ this.renderFlowsWebGL();
+
// Draw nodes
this.renderNodesWebGL();
}
@@ -337,9 +421,9 @@ class NeuralNetworkBackground {
positions[i * 2] = node.x;
positions[i * 2 + 1] = node.y;
- // Size with pulse effect
- const pulse = Math.sin(node.pulsePhase) * 0.3 + 1;
- sizes[i] = node.size * pulse * (node.connections.length > 3 ? 1.5 : 1);
+ // Size with subtle pulse effect
+ const pulse = Math.sin(node.pulsePhase) * 0.2 + 1;
+ sizes[i] = node.size * pulse * (node.connections.length > 3 ? 1.3 : 1);
}
// Bind position buffer
@@ -368,7 +452,7 @@ class NeuralNetworkBackground {
);
this.gl.enableVertexAttribArray(this.programInfo.attribLocations.pointSize);
- // Set node color
+ // Set node color - more subtle
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
const nodeColor = this.hexToRgb(colorObj.nodeColor);
this.gl.uniform4f(
@@ -376,12 +460,12 @@ class NeuralNetworkBackground {
nodeColor.r / 255,
nodeColor.g / 255,
nodeColor.b / 255,
- 0.8 // Alpha
+ 0.7 // Lower opacity for subtlety
);
// Draw nodes
this.gl.enable(this.gl.BLEND);
- this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
+ this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE); // Additive blending for glow
this.gl.drawArrays(this.gl.POINTS, 0, this.nodes.length);
}
@@ -413,7 +497,7 @@ class NeuralNetworkBackground {
// Disable point size attribute for lines
this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize);
- // Set line color with connection opacity
+ // Set line color with connection opacity - darker, more subtle
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
const lineColor = this.hexToRgb(colorObj.connectionColor);
this.gl.uniform4f(
@@ -421,22 +505,9 @@ class NeuralNetworkBackground {
lineColor.r / 255,
lineColor.g / 255,
lineColor.b / 255,
- connection.opacity
+ connection.opacity * 0.8 // Reduced for subtlety
);
- // Data pulse animation along connection
- if (Math.random() < 0.01 && fromNode.connections.length > 2) {
- // Draw data pulse (slightly different color)
- const pulseColor = this.hexToRgb(colorObj.nodePulse);
- this.gl.uniform4f(
- this.programInfo.uniformLocations.color,
- pulseColor.r / 255,
- pulseColor.g / 255,
- pulseColor.b / 255,
- 0.8
- );
- }
-
// Draw the line
this.gl.enable(this.gl.BLEND);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
@@ -445,6 +516,94 @@ class NeuralNetworkBackground {
}
}
+ // New method to render the flowing animations
+ renderFlowsWebGL() {
+ // For each flow, draw a segment along its connection
+ for (const flow of this.flows) {
+ const connection = flow.connection;
+ const fromNode = this.nodes[connection.from];
+ const toNode = this.nodes[connection.to];
+
+ // Calculate flow position
+ const startProgress = flow.progress;
+ const endProgress = Math.min(1, startProgress + flow.length);
+
+ // If flow hasn't started yet or has finished
+ if (startProgress >= 1 || endProgress <= 0) continue;
+
+ // Calculate actual positions
+ const direction = flow.direction ? 1 : -1;
+ let p1, p2;
+
+ if (direction > 0) {
+ p1 = {
+ x: fromNode.x + (toNode.x - fromNode.x) * startProgress,
+ y: fromNode.y + (toNode.y - fromNode.y) * startProgress
+ };
+ p2 = {
+ x: fromNode.x + (toNode.x - fromNode.x) * endProgress,
+ y: fromNode.y + (toNode.y - fromNode.y) * endProgress
+ };
+ } else {
+ p1 = {
+ x: toNode.x + (fromNode.x - toNode.x) * startProgress,
+ y: toNode.y + (fromNode.y - toNode.y) * startProgress
+ };
+ p2 = {
+ x: toNode.x + (fromNode.x - toNode.x) * endProgress,
+ y: toNode.y + (fromNode.y - toNode.y) * endProgress
+ };
+ }
+
+ // Line positions for the flow
+ const positions = new Float32Array([
+ p1.x, p1.y,
+ p2.x, p2.y
+ ]);
+
+ // Bind position buffer
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
+ this.gl.vertexAttribPointer(
+ this.programInfo.attribLocations.vertexPosition,
+ 2, // components per vertex
+ this.gl.FLOAT, // data type
+ false, // normalize
+ 0, // stride
+ 0 // offset
+ );
+ this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition);
+
+ // Disable point size attribute for lines
+ this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize);
+
+ // Fade the flow at the beginning and end
+ const fadeEdge = 0.2;
+ const fadeOpacity = Math.min(
+ startProgress / fadeEdge,
+ (1 - endProgress) / fadeEdge,
+ 1
+ );
+
+ // Flow color - subtle glow
+ const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
+ const flowColor = this.hexToRgb(colorObj.flowColor);
+ this.gl.uniform4f(
+ this.programInfo.uniformLocations.color,
+ flowColor.r / 255,
+ flowColor.g / 255,
+ flowColor.b / 255,
+ 0.4 * fadeOpacity // Subtle flow opacity
+ );
+
+ // Draw the flow line
+ this.gl.enable(this.gl.BLEND);
+ this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
+ this.gl.lineWidth(1.5); // Slightly thicker for visibility
+ this.gl.drawArrays(this.gl.LINES, 0, 2);
+ }
+ }
+
renderCanvas() {
// Clear canvas
const width = this.canvas.width / (window.devicePixelRatio || 1);
@@ -478,6 +637,9 @@ class NeuralNetworkBackground {
this.ctx.stroke();
}
+ // Draw flows
+ this.renderFlowsCanvas();
+
// Draw nodes
const nodeColor = this.isDarkMode
? this.darkModeColors.nodeColor
@@ -488,9 +650,9 @@ class NeuralNetworkBackground {
: this.lightModeColors.nodePulse;
for (const node of this.nodes) {
- // Node with glow effect
- const pulse = Math.sin(node.pulsePhase) * 0.3 + 1;
- const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.5 : 1);
+ // Node with subtle glow effect
+ const pulse = Math.sin(node.pulsePhase) * 0.2 + 1;
+ const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.3 : 1);
// Glow effect
const glow = this.ctx.createRadialGradient(
@@ -501,7 +663,7 @@ class NeuralNetworkBackground {
const rgbNodeColor = this.hexToRgb(nodeColor);
const rgbPulseColor = this.hexToRgb(nodePulse);
- glow.addColorStop(0, `rgba(${rgbPulseColor.r}, ${rgbPulseColor.g}, ${rgbPulseColor.b}, 0.8)`);
+ glow.addColorStop(0, `rgba(${rgbPulseColor.r}, ${rgbPulseColor.g}, ${rgbPulseColor.b}, 0.6)`);
glow.addColorStop(0.5, `rgba(${rgbNodeColor.r}, ${rgbNodeColor.g}, ${rgbNodeColor.b}, 0.2)`);
glow.addColorStop(1, `rgba(${rgbNodeColor.r}, ${rgbNodeColor.g}, ${rgbNodeColor.b}, 0)`);
@@ -518,18 +680,89 @@ class NeuralNetworkBackground {
}
}
+ // New method to render flows in Canvas mode
+ renderFlowsCanvas() {
+ if (!this.ctx) return;
+
+ const flowColor = this.isDarkMode
+ ? this.darkModeColors.flowColor
+ : this.lightModeColors.flowColor;
+
+ const rgbFlowColor = this.hexToRgb(flowColor);
+
+ for (const flow of this.flows) {
+ const connection = flow.connection;
+ const fromNode = this.nodes[connection.from];
+ const toNode = this.nodes[connection.to];
+
+ // Calculate flow position
+ const startProgress = flow.progress;
+ const endProgress = Math.min(1, startProgress + flow.length);
+
+ // If flow hasn't started yet or has finished
+ if (startProgress >= 1 || endProgress <= 0) continue;
+
+ // Calculate actual positions
+ const direction = flow.direction ? 1 : -1;
+ let p1, p2;
+
+ if (direction > 0) {
+ p1 = {
+ x: fromNode.x + (toNode.x - fromNode.x) * startProgress,
+ y: fromNode.y + (toNode.y - fromNode.y) * startProgress
+ };
+ p2 = {
+ x: fromNode.x + (toNode.x - fromNode.x) * endProgress,
+ y: fromNode.y + (toNode.y - fromNode.y) * endProgress
+ };
+ } else {
+ p1 = {
+ x: toNode.x + (fromNode.x - toNode.x) * startProgress,
+ y: toNode.y + (fromNode.y - toNode.y) * startProgress
+ };
+ p2 = {
+ x: toNode.x + (fromNode.x - toNode.x) * endProgress,
+ y: toNode.y + (fromNode.y - toNode.y) * endProgress
+ };
+ }
+
+ // Fade the flow at the beginning and end
+ const fadeEdge = 0.2;
+ const fadeOpacity = Math.min(
+ startProgress / fadeEdge,
+ (1 - endProgress) / fadeEdge,
+ 1
+ );
+
+ // Draw flow
+ this.ctx.beginPath();
+ this.ctx.moveTo(p1.x, p1.y);
+ this.ctx.lineTo(p2.x, p2.y);
+ this.ctx.strokeStyle = `rgba(${rgbFlowColor.r}, ${rgbFlowColor.g}, ${rgbFlowColor.b}, ${0.4 * fadeOpacity})`;
+ this.ctx.lineWidth = 1.5;
+ this.ctx.stroke();
+ }
+ }
+
// Helper method to convert hex to RGB
hexToRgb(hex) {
// Remove # if present
hex = hex.replace(/^#/, '');
+ // Handle rgba hex format
+ let alpha = 1;
+ if (hex.length === 8) {
+ alpha = parseInt(hex.slice(6, 8), 16) / 255;
+ hex = hex.slice(0, 6);
+ }
+
// Parse hex values
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
- return { r, g, b };
+ return { r, g, b, a: alpha };
}
// Cleanup method
@@ -555,7 +788,21 @@ class NeuralNetworkBackground {
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
- window.neuralNetworkBackground = new NeuralNetworkBackground();
+ // Short delay to ensure DOM is fully loaded
+ setTimeout(() => {
+ if (!window.neuralNetworkBackground) {
+ console.log('Creating Neural Network Background');
+ window.neuralNetworkBackground = new NeuralNetworkBackground();
+ }
+ }, 100);
+});
+
+// Re-initialize when page is fully loaded (for safety)
+window.addEventListener('load', () => {
+ if (!window.neuralNetworkBackground) {
+ console.log('Re-initializing Neural Network Background on full load');
+ window.neuralNetworkBackground = new NeuralNetworkBackground();
+ }
});
// Clean up when window is closed
diff --git a/website/static/style.css b/website/static/style.css
index c387931..9e05d85 100644
--- a/website/static/style.css
+++ b/website/static/style.css
@@ -43,16 +43,24 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
transition: background-color var(--transition-normal), color var(--transition-normal);
+ background-color: transparent !important; /* Ensure background is transparent */
}
-/* Theme Specific */
+/* HTML root element should also be transparent */
+html {
+ background-color: transparent !important;
+}
+
+html.dark {
+ background-color: transparent !important;
+}
+
+/* Theme Specific - keep the color but remove background */
body {
- background-color: var(--light-bg-primary);
color: var(--light-text-primary);
}
body.dark {
- background-color: var(--dark-bg-primary);
color: var(--dark-text-primary);
}
diff --git a/website/templates/base.html b/website/templates/base.html
index 35664a3..35f218a 100644
--- a/website/templates/base.html
+++ b/website/templates/base.html
@@ -83,6 +83,9 @@
+
+
+