#include <metal_stdlib>

using namespace metal;
struct buf0 {
  /* 0x0000 */ packed_float2 injectionSwitch;
};
struct tint_array_wrapper {
  float2 arr[17];
};
struct main_out {
  float4 x_GLF_color_1;
};
struct tint_symbol_2 {
  float4 x_GLF_color_1 [[color(0)]];
};

float func_(constant buf0& x_7, thread float4* const tint_symbol_5) {
  int x = 0;
  float const x_99 = (*(tint_symbol_5)).x;
  if ((x_99 < 1.0f)) {
    return 5.0f;
  }
  float const x_104 = x_7.injectionSwitch.x;
  float const x_106 = x_7.injectionSwitch.y;
  if ((x_104 > x_106)) {
    return 1.0f;
  }
  float const x_111 = x_7.injectionSwitch.x;
  x = int(x_111);
  float const x_114 = x_7.injectionSwitch.x;
  int const x_118 = x;
  x = as_type<int>((as_type<uint>(x_118) + as_type<uint>(as_type<int>((as_type<uint>(int(clamp(x_114, 0.0f, 1.0f))) * as_type<uint>(3))))));
  int const x_120 = x;
  return (5.0f + float(x_120));
}

void main_1(constant buf0& x_7, thread float4* const tint_symbol_6, thread float4* const tint_symbol_7) {
  int i = 0;
  int j = 0;
  tint_array_wrapper data = {};
  i = 0;
  while (true) {
    int const x_48 = i;
    float const x_50 = x_7.injectionSwitch.x;
    if ((x_48 < as_type<int>((as_type<uint>(4) + as_type<uint>(int(x_50)))))) {
    } else {
      break;
    }
    float const x_56 = (*(tint_symbol_6)).x;
    if ((x_56 >= 0.0f)) {
      j = 0;
      while (true) {
        bool x_81 = false;
        bool x_82_phi = false;
        int const x_64 = j;
        if ((x_64 < 4)) {
        } else {
          break;
        }
        int const x_67 = j;
        int const x_69 = i;
        float const x_71 = func_(x_7, tint_symbol_6);
        data.arr[as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(4) * as_type<uint>(x_67)))) + as_type<uint>(x_69)))].x = x_71;
        float const x_74 = data.arr[0].x;
        bool const x_75 = (x_74 == 5.0f);
        x_82_phi = x_75;
        if (!(x_75)) {
          float const x_80 = data.arr[15].x;
          x_81 = (x_80 == 5.0f);
          x_82_phi = x_81;
        }
        bool const x_82 = x_82_phi;
        if (x_82) {
          *(tint_symbol_7) = float4(1.0f, 0.0f, 0.0f, 1.0f);
        } else {
          *(tint_symbol_7) = float4(0.0f, 0.0f, 0.0f, 0.0f);
        }
        float const x_87 = x_7.injectionSwitch.x;
        float const x_89 = x_7.injectionSwitch.y;
        if ((x_87 > x_89)) {
          return;
        }
        {
          int const x_93 = j;
          j = as_type<int>((as_type<uint>(x_93) + as_type<uint>(1)));
        }
      }
    }
    {
      int const x_95 = i;
      i = as_type<int>((as_type<uint>(x_95) + as_type<uint>(1)));
    }
  }
  return;
}

fragment tint_symbol_2 tint_symbol(float4 gl_FragCoord_param [[position]], constant buf0& x_7 [[buffer(0)]]) {
  thread float4 tint_symbol_8 = 0.0f;
  thread float4 tint_symbol_9 = 0.0f;
  tint_symbol_8 = gl_FragCoord_param;
  main_1(x_7, &(tint_symbol_8), &(tint_symbol_9));
  main_out const tint_symbol_3 = {.x_GLF_color_1=tint_symbol_9};
  tint_symbol_2 const tint_symbol_4 = {.x_GLF_color_1=tint_symbol_3.x_GLF_color_1};
  return tint_symbol_4;
}

