master f7179d1bbb51 cached
9 files
15.8 KB
5.0k tokens
1 requests
Download .txt
Repository: Shrimpey/Outlined-Diffuse-Shader-Fixed
Branch: master
Commit: f7179d1bbb51
Files: 9
Total size: 15.8 KB

Directory structure:
gitextract_6ztqttvw/

├── CustomOutline-CameraIndependent.shader
├── CustomOutline-ConstantWidth.shader
├── CustomOutline.shader
├── LICENSE
├── OutlineShowcase.unitypackage
├── README.md
├── RegularOutline.shader
├── UniformOutline.shader
└── triangleOutline.shader

================================================
FILE CONTENTS
================================================

================================================
FILE: CustomOutline-CameraIndependent.shader
================================================
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Outlined/Custom Camera Independent" {
	Properties {
		_Color ("Main Color", Color) = (.5,.5,.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline2 ("Outline width", Range (0, 1)) = .1
		_MainTex ("Base (RGB)", 2D) = "white" { }
	}
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};
 
struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};
 
uniform float _Outline2;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
	// just make a copy of incoming vertex data but scaled according to normal direction
	v2f o;

	//Camera position in world
	float3 targetPos = _WorldSpaceCameraPos;

	//Object position in world
	float3 objectPos = mul (unity_ObjectToWorld, v.vertex).xyz;

	//Vertex offset from center of the object
	float3 offset = v.vertex.xyz;

	//Distance from the object to the camera
	float dist = distance(objectPos, targetPos + offset);

	//Forward vector of the camera
	float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;

	//Vector between vertex and offseted camera pos
	float3 distVec = objectPos - (targetPos + offset);

	//Angle between two vectors
	float angle = distVec - distVec;
	//float angle = atan2(normalize(cross(distVec,viewDir)), dot(distVec,viewDir));

	//Real distance (to the plane 90 degrees to camera forward and object)
	float finalDist = dist * cos(degrees(angle));

	//v.vertex *= ( 2 );
	v.vertex *= finalDist * _Outline2;

	//v.vertex *= -1;

	o.pos = UnityObjectToClipPos(v.vertex);

	o.color = _OutlineColor;
	return o;
}
ENDCG
 
	SubShader {
		//Tags {"Queue" = "Geometry+100" }
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		// note that a vertex shader is specified here but its using the one above
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
 
	SubShader {
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
 
			CGPROGRAM
			#pragma vertex vert
			#pragma exclude_renderers gles xbox360 ps3
			ENDCG
			SetTexture [_MainTex] { combine primary }
		}
	}
 
	Fallback "Diffuse"
}


================================================
FILE: CustomOutline-ConstantWidth.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Outlined/Custom Constant Width" {
	Properties {
		_Color ("Main Color", Color) = (.5,.5,.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline ("Outline width", Range (0, 5)) = .1
		_Limiter ("Outline width limiter", Range (0, 5)) = 0
		_MainTex ("Base (RGB)", 2D) = "white" { }
	}
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};
 
struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};
 
uniform float _Outline;
uniform float _Limiter;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {

	v2f o;

	//Original concept of using FOV
	//float t = unity_CameraProjection._m11;
    //const float Rad2Deg = 180 / UNITY_PI;
    //float fov = atan(1.0f / t ) * 2.0 * Rad2Deg;

    //if(fov < _Limiter){
    //	fov = _Limiter;
    //}

    float multiplier = unity_OrthoParams.x * 0.1;

    if(multiplier < _Limiter){
    	multiplier = _Limiter;
    }

	v.vertex *=  _Outline * multiplier;

	o.pos = UnityObjectToClipPos(v.vertex);

	o.color = _OutlineColor;
	return o;
}
ENDCG
 
	SubShader {
		//Tags {"Queue" = "Geometry+100" }
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		// note that a vertex shader is specified here but its using the one above
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
 
	SubShader {
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
 
			CGPROGRAM
			#pragma vertex vert
			#pragma exclude_renderers gles xbox360 ps3
			ENDCG
			SetTexture [_MainTex] { combine primary }
		}
	}
 
	Fallback "Diffuse"
}


================================================
FILE: CustomOutline.shader
================================================
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Outlined/Custom" {
	Properties {
		_Color ("Main Color", Color) = (.5,.5,.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline ("Outline width", Range (0, 1)) = .1
		_MainTex ("Base (RGB)", 2D) = "white" { }
	}
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};
 
struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};
 
uniform float _Outline;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
	// just make a copy of incoming vertex data but scaled according to normal direction
	v2f o;

	v.vertex *= ( 1 + _Outline);

	o.pos = UnityObjectToClipPos(v.vertex);
 
	//float3 norm   = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));
	//float2 offset = TransformViewToProjection(norm.xy);

	o.color = _OutlineColor;
	return o;
}
ENDCG
 
	SubShader {
		//Tags {"Queue" = "Geometry+100" }
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		// note that a vertex shader is specified here but its using the one above
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
			//Offset 50,50
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
 
	SubShader {
CGPROGRAM
#pragma surface surf Lambert
 
sampler2D _MainTex;
fixed4 _Color;
 
struct Input {
	float2 uv_MainTex;
};
 
void surf (Input IN, inout SurfaceOutput o) {
	fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
	o.Albedo = c.rgb;
	o.Alpha = c.a;
}
ENDCG
 
		Pass {
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Front
			ZWrite On
			ColorMask RGB
			Blend SrcAlpha OneMinusSrcAlpha
 
			CGPROGRAM
			#pragma vertex vert
			#pragma exclude_renderers gles xbox360 ps3
			ENDCG
			SetTexture [_MainTex] { combine primary }
		}
	}
 
	Fallback "Diffuse"
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Luke Kabat

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Outlined Diffuse Shader Fixed for Unity 5.6
This is a fixed version of diffused outline shader from http://wiki.unity3d.com/index.php/Outlined_Diffuse_3
It should be working fine in Unity 5.6 and above.

# Important update:
**A new version of the outline shader is available, go to: https://github.com/Shrimpey/UltimateOutline
Use the updated shader, come back here only if you find it to be working weirdly on your custom models and try some of the ones mentioned below.**

**Guide:**
I suggest you trying **UniformOutline.shader** and then **CustomOutline.shader**. They should work fine for simple objects/complex objects with proper origin. If they fail - try out the **RegularOutline.shader**. The rest of the shaders are for really specyfic purposes, so unless you know what you're doing you probably shouldn't be using them :)

**Showcase:**
Download **OutlineShowcase.unitypackage** and import it to Unity project to see RegularOutline, CustomOutline and UniformOutline shaders in action.

**Shaders:**

# RegularOutline.shader
**RegularOutline.shader** - Just an updated version of the shader from the wiki page, may still work in weird ways => if so, use custom one.
![Regular Outline](/images/standard.PNG?raw=true "Regular Outline")
**Usage**: Curved shapes/thin outlines.
**Problems**: Weird shapes on hard edges.

---
# CustomOutline.shader
**CustomOutline.shader** - My personal take on the outline shader. It increases the scale of the vertices instead of working with normals. 
![Custom Outline](/images/custom.PNG?raw=true "Custom Outline")
**Usage**: All shapes
**Problems**: Possible clipping on really thick edges/weird offsets if model's origin is not in center

---
# UniformOutline.shader
**UniformOutline.shader** - Made from scratch, works just like CustomOutline except the scaling is more uniform - width of the outline should be more consistent on irregular meshes (easy to notice when comparing the wheels of the cart from the image below to the Custom Outline shader image). 

![Uniform Outline](/images/Uniform.PNG?raw=true "Uniform Outline")

**Usage**: All shapes
**Problems**: Same as in Custom Outline, less overlaying, more angled distortions.

---
# CustomOutline-CameraIndependent.shader
**CustomOutline-CameraIndependent.shader** - Same as custom one, but the outline is the same width despite the distance to the camera. 

![Camera Independend Close](/images/camera.PNG?raw=true "Camera Independend Close")
![Camera Independend Far](/images/camera2.PNG?raw=true "Camera Independend Far")

**Usage**: Same sized outline on perspective camera.
**Problems**: Weird shapes on complex objects.

---
# CustomOutline-ConstantWidth.shader
**CustomOutline-ConstantWidth.shader** - Same as custom one, but the outline is constant width despite the camera zoom.

![Constant Width Zoomed In](/images/zoom2.PNG?raw=true "Constant Width Zoomed In")
![Constant Width Zoomed Out](/images/zoom.PNG?raw=true "Constant Width Zoomed Out")

**Usage**: Same outline width despite the camera's zoom (ortho/perspective)
**Problems**: Clipping on thick outlines on complex shapes.

---


*UPDATE 03.09.2017 - Added camera independent version of custom shader*

*UPDATE 04.09.2017 - Added constant size version of custom shader | updated README to include images*

*UPDATE 12.09.2017 - Added uniform outline shader*

*UPDATE 23.12.2017 - Fixed some minor issues with custom, regular and uniform shaders | added showcase unity package*


================================================
FILE: RegularOutline.shader
================================================
Shader "Outlined/Regular" {
	Properties {
		_Color ("Main Color", Color) = (.5,.5,.5,1)
		_OutlineColor ("Outline Color", Color) = (0,0,0,1)
		_Outline ("Outline width", Range (0, 1)) = .1
		_MainTex ("Base (RGB)", 2D) = "white" { }
	}
 
CGINCLUDE
#include "UnityCG.cginc"
 
struct appdata {
	float4 vertex : POSITION;
	float3 normal : NORMAL;
};
 
struct v2f {
	float4 pos : POSITION;
	float4 color : COLOR;
};
 
uniform float _Outline;
uniform float4 _OutlineColor;
 
v2f vert(appdata v) {
	// just make a copy of incoming vertex data but scaled according to normal direction
	v2f o;
	o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 
	float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
	float2 offset = TransformViewToProjection(norm.xy);
 
	o.pos.xy += offset * o.pos.z * _Outline;
	o.color = _OutlineColor;
	return o;
}
ENDCG
 
	SubShader {
		Tags { "Queue" = "Transparent" "IgnoreProjector" = "True"}
		Cull Back
		CGPROGRAM
		#pragma surface surf Lambert
		 
		sampler2D _MainTex;
		fixed4 _Color;
		 
		struct Input {
			float2 uv_MainTex;
		};
		 
		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG

		Pass {
			Name "OUTLINE"
			Tags { "Queue" = "Transparent" "IgnoreProjector" = "True"}
			Cull Front
			ZWrite Off
			//ZTest Less
			//Offset 1, 1
 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			half4 frag(v2f i) :COLOR { return i.color; }
			ENDCG
		}
	}
 
	Fallback "Diffuse"
}


================================================
FILE: UniformOutline.shader
================================================
Shader "Outlined/Uniform"
{
	Properties
	{
		_Color("Main Color", Color) = (0.5,0.5,0.5,1)
		_MainTex ("Texture", 2D) = "white" {}
		_OutlineColor ("Outline color", Color) = (0,0,0,1)
		_OutlineWidth ("Outlines width", Range (0.0, 2.0)) = 1.1
	}

	CGINCLUDE
	#include "UnityCG.cginc"

	struct appdata
	{
		float4 vertex : POSITION;
	};

	struct v2f
	{
		float4 pos : POSITION;
	};

	uniform float _OutlineWidth;
	uniform float4 _OutlineColor;
	uniform sampler2D _MainTex;
	uniform float4 _Color;

	ENDCG

	SubShader
	{
		Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" }

		Pass //Outline
		{
			ZWrite Off
			Cull Back
			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			v2f vert(appdata v)
			{
				appdata original = v;
				v.vertex.xyz += _OutlineWidth * normalize(v.vertex.xyz);

				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				return o;

			}

			half4 frag(v2f i) : COLOR
			{
				return _OutlineColor;
			}

			ENDCG
		}

		Tags{ "Queue" = "Geometry"}

		CGPROGRAM
		#pragma surface surf Lambert
		 
		struct Input {
			float2 uv_MainTex;
		};
		 
		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	Fallback "Diffuse"
}


================================================
FILE: triangleOutline.shader
================================================
Shader "Outlined/Triangle"
{
	Properties
	{
		_Color("Main Color", Color) = (0.5,0.5,0.5,1)
		_MainTex ("Texture", 2D) = "white" {}
		_OutlineColor ("Outline color", Color) = (0,0,0,1)
		_OutlineWidth ("Outlines width", Range (0.0, 2.0)) = 1.1
	}

	CGINCLUDE
	#include "UnityCG.cginc"

	struct appdata
	{
		float4 vertex : POSITION;
	};

	struct v2f
	{
		float4 pos : POSITION;
	};

	uniform float _OutlineWidth;
	uniform float4 _OutlineColor;
	uniform sampler2D _MainTex;
	uniform float4 _Color;

	ENDCG

	SubShader
	{
		Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" }

		Pass //Outline
		{
			ZWrite Off
			Cull Back
			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			v2f vert(appdata v)
			{
				appdata original = v;
				v.vertex.xyzw += _OutlineWidth * normalize(v.vertex.xyzw);
				v.vertex.x -= _OutlineWidth/4;
				v.vertex.y += _OutlineWidth/4;

				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				return o;

			}

			half4 frag(v2f i) : COLOR
			{
				return _OutlineColor;
			}

			ENDCG
		}

		Tags{ "Queue" = "Geometry"}

		CGPROGRAM
		#pragma surface surf Lambert
		 
		struct Input {
			float2 uv_MainTex;
		};
		 
		void surf (Input IN, inout SurfaceOutput o) {
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	Fallback "Diffuse"
}
Download .txt
gitextract_6ztqttvw/

├── CustomOutline-CameraIndependent.shader
├── CustomOutline-ConstantWidth.shader
├── CustomOutline.shader
├── LICENSE
├── OutlineShowcase.unitypackage
├── README.md
├── RegularOutline.shader
├── UniformOutline.shader
└── triangleOutline.shader
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (18K chars).
[
  {
    "path": "CustomOutline-CameraIndependent.shader",
    "chars": 2970,
    "preview": "// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'\n\n// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)"
  },
  {
    "path": "CustomOutline-ConstantWidth.shader",
    "chars": 2414,
    "preview": "// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'\n\nShader \"Outlined/Custom Constant Wid"
  },
  {
    "path": "CustomOutline.shader",
    "chars": 2185,
    "preview": "// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'\n\nShader \"Outlined/Custom\" {\n\tProperti"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2017 Luke Kabat\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 3452,
    "preview": "# Outlined Diffuse Shader Fixed for Unity 5.6\nThis is a fixed version of diffused outline shader from http://wiki.unity3"
  },
  {
    "path": "RegularOutline.shader",
    "chars": 1517,
    "preview": "Shader \"Outlined/Regular\" {\n\tProperties {\n\t\t_Color (\"Main Color\", Color) = (.5,.5,.5,1)\n\t\t_OutlineColor (\"Outline Color\""
  },
  {
    "path": "UniformOutline.shader",
    "chars": 1269,
    "preview": "Shader \"Outlined/Uniform\"\n{\n\tProperties\n\t{\n\t\t_Color(\"Main Color\", Color) = (0.5,0.5,0.5,1)\n\t\t_MainTex (\"Texture\", 2D) = "
  },
  {
    "path": "triangleOutline.shader",
    "chars": 1342,
    "preview": "Shader \"Outlined/Triangle\"\n{\n\tProperties\n\t{\n\t\t_Color(\"Main Color\", Color) = (0.5,0.5,0.5,1)\n\t\t_MainTex (\"Texture\", 2D) ="
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the Shrimpey/Outlined-Diffuse-Shader-Fixed GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (15.8 KB), approximately 5.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!