используя эти функции перепиши мой JS angular код в код для gta samp на Lua (для moonloader)

angular.module('beamng.apps')
.directive('classicSpeedo', [function () {
  return {
    template: '<div style="overflow: hidden;"><canvas id="cSpeedo" height="90px"></canvas></div>',
    replace: true,
    restrict: 'EA',
    link: function (scope, element, attrs) {

        var streams = ['electrics'];
        StreamsManager.add(streams);
        scope.$on('$destroy', function () {
            StreamsManager.remove(streams);
        });

        var canvas = element.find("canvas")[0];
        scope.currentTheme = getTheme();
        var values = [];

        scope.$on('streamsUpdate', function (event, streams) {

            canvas.width = element[0].clientWidth;
            canvas.height = canvas.width * 3.3333;

            var w = canvas.width;
            var h = canvas.height;
            var scale = w / 200;

            var speedMs = 0;
            try {
                speedMs = streams.electrics.wheelspeed;
            } catch(e) {}
            if (isNaN(speedMs)) speedMs = streams.electrics.airspeed;
            var speedConverted = UiUnits.speed(speedMs);
            if(speedConverted === null) return;
            var speedUnits = Math.round(speedConverted.val);

            var speedStart;
            //for resetting scale >160
            if (speedUnits > 160) {
                speedStart = 160;
            } else {
                speedStart = 0;
            }

            var ctx = canvas.getContext('2d');

            ctx.scale(scale, scale);

            ctx.clearRect(0,0,200,65);
            ctx.fillStyle = scope.currentTheme.background;
            ctx.fillRect(0, 0, 200, 65);


            if (speedStart === 0){
                ctx.fillStyle = scope.currentTheme.speed1;
            } else {
                ctx.fillStyle = scope.currentTheme.speed2;
            }

            ctx.fillRect(20,10,Math.min(speedUnits-speedStart, 160),25);


            ctx.fillStyle = scope.currentTheme.text;
            //-Numbers
            ctx.font='8px Arial';
            ctx.textAlign="center";

            var interval = 20;
            for (var x=0; x<=160; x+=interval) {
                ctx.fillText(speedStart+x,x+20,48);
            }

            ctx.font='20px Arial';
            ctx.fillText(pad(speedUnits, 3), 100, 30);

            ctx.font='10px Arial';
            ctx.fillText("Speed (" + UiUnits.speed().unit.toUpperCase() + ")", 100, 62);

            //Add Graduations
            //20px/20unit intervals
            ctx.strokeStyle = scope.currentTheme.border;
            for (var x1=20; x1<=180; x1+=interval) {
                ctx.beginPath();
                ctx.moveTo(x1, 35);
                ctx.lineTo(x1, 40);
                ctx.stroke();
            }
            //and 10px/10unit intervals
            for (var x2=30; x2<=180; x2+=interval) {
                ctx.beginPath();
                ctx.moveTo(x2, 35);
                ctx.lineTo(x2, 38);
                ctx.stroke();
            }

            //add border
            ctx.strokeStyle = scope.currentTheme.border;
            ctx.lineWidth = 1;
            ctx.strokeRect(20,10,160,25);
        });

        scope.$on('ClassicUI', function (event, state) {
            if(state == "updateTheme") {
                scope.currentTheme = getTheme();
            }
        });

        function getTheme() {
            var themeStyles = parseInt(getDefaultValue("themeMode", 0));
            var tmpTheme;
            if(themeStyles == 0) {
                tmpTheme = {
                    background: 'rgba(255, 255, 255, 0.9)',
                    text: 'rgba(0, 0, 0, 0.9)',
                    border: 'rgba(0, 0, 0, 0.9)',

                    speed1: 'rgba(0, 0, 255, 0.5)',
                    speed2: 'rgba(255, 0, 255, 0.5)',
                };
            } 
            if(themeStyles == 1) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.9)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(160, 160, 160)',

                    speed1: 'rgba(80, 80, 255, 0.5)',
                    speed2: 'rgba(255, 80, 255, 0.5)',
                };
            }
            if(themeStyles == 2) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.43)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(80, 80, 80)',

                    speed1: 'rgba(80, 80, 255, 0.5)',
                    speed2: 'rgba(255, 80, 255, 0.5)',
                };
            }
            return tmpTheme;
        }

        function pad(num, size) {
            var s = num+"";
            while (s.length < size) s = "0" + s;
            return s;
        }

        function getDefaultValue(type, defVal) {
            return localStorage.getItem("classicUI_" + type) || defVal;
        }
    }
  };
}]);


angular.module('beamng.apps')
.directive('classicTacho', [function () {
  return {
    template: '<div style="overflow: hidden;"><canvas id="cTacho" height="90px"></canvas></div>',
    replace: true,
    restrict: 'EA',
    link: function (scope, element, attrs) {
        var streams = ['electrics', 'engineInfo'];
        StreamsManager.add(streams);
        scope.$on('$destroy', function () {
            StreamsManager.remove(streams);
        });

        var canvas = element.find("canvas")[0];
        scope.currentTheme = getTheme();

        scope.$on('streamsUpdate', function (event, streams) {
            canvas.width = element[0].clientWidth;
            canvas.height = canvas.width * 3.3333;
            
            var rpm = Math.round(Number(streams.engineInfo[4]));
            var rpmMax = streams.engineInfo[1];
            var rpmIdle = streams.engineInfo[0];
            
            var w = canvas.width;
            var h = canvas.height;
            var scale = w / 200;

            //console.log(scale);

            var ctx = canvas.getContext('2d');

            ctx.scale(scale, scale);
            ctx.clearRect(0, 0, w, h);
            ctx.fillStyle = scope.currentTheme.background;
            ctx.fillRect(0, 0, w, h);
            var rgba = '';
            if(rpm < rpmIdle*1.25) {
                rgba = scope.currentTheme.engIdle;
            } else if(rpm > rpmMax*0.9) {
                rgba = scope.currentTheme.engRedline;
            } else {
                rgba = scope.currentTheme.engNormal;
            }
            ctx.fillStyle = rgba;

            var fillAmount = Math.abs(rpm/(rpmMax/160));

            if(fillAmount > 160) fillAmount = 160;
            ctx.fillRect(20, 10, fillAmount, 25);

            ctx.font='20px Arial';
            ctx.textAlign="center";

            ctx.fillStyle = scope.currentTheme.text;
            ctx.fillText(pad(Math.abs(rpm), 4),100,30);

            ctx.font='10px Arial';
            ctx.fillText("Engine RPM",100,62);

            ctx.font='10px Arial';
            ctx.fillText("0000",20,48);
            ctx.fillText(rpmMax,180,48);

            ctx.strokeStyle = scope.currentTheme.border;
            ctx.lineWidth = 1;
            ctx.strokeRect(20,10,160,25);
        });


        scope.$on('ClassicUI', function (event, state) {
            if(state == "updateTheme") {
                scope.currentTheme = getTheme();
            }
        });

        function getTheme() {
            var themeStyles = parseInt(getDefaultValue("themeMode", 0));
            var tmpTheme;
            if(themeStyles == 0) {
                tmpTheme = {
                    background: 'rgba(255, 255, 255, 0.9)',
                    text: 'rgba(0, 0, 0, 0.9)',
                    border: 'rgba(0, 0, 0, 0.9)',

                    engIdle: 'rgba(0, 0, 255, 0.5)',
                    engRedline: 'rgba(255, 0, 0, 0.5)',
                    engNormal: 'rgba(0, 255, 0, 0.5)',
                };
            }
            if(themeStyles == 1) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.9)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(160, 160, 160)',

                    engIdle: 'rgba(80, 80, 255, 0.5)',
                    engRedline: 'rgba(255, 80, 80, 0.5)',
                    engNormal: 'rgba(80, 255, 80, 0.5)',
                };
            }
            if(themeStyles == 2) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.43)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(80, 80, 80)',

                    engIdle: 'rgba(80, 80, 255, 0.5)',
                    engRedline: 'rgba(255, 80, 80, 0.5)',
                    engNormal: 'rgba(80, 255, 80, 0.5)',
                };
            }
            return tmpTheme;
        }
        function pad(num, size) {
            var s = num+"";
            while (s.length < size) s = "0" + s;
            return s;
        }

        function getDefaultValue(type, defVal) {
            return localStorage.getItem("classicUI_" + type) || defVal;
        }

    }
  };
}]);


angular.module('beamng.apps')
.directive('classicPedals', [function() {
  return {
    template: '<div style="overflow: hidden;"><canvas id="cPedals"></canvas></div>',
    replace: true,
    restrict: 'EA',
    link: function (scope, element, attrs) {
        StreamsManager.add(['electrics']);

        scope.$on('$destroy', function () {
            StreamsManager.remove(['electrics']);
        });

        var canvas = element.find("canvas")[0];
        scope.currentTheme = getTheme();

        scope.$on('streamsUpdate', function (event, streams) {
            canvas.width = element[0].clientWidth;
            canvas.height = canvas.width / 1.4444;

            var w = canvas.width;
            var h = canvas.height;
            var scale = w / 100;

            //console.log(scale);

            var ctx = canvas.getContext('2d');

            ctx.scale(scale, scale);
            ctx.clearRect(0, 0, w, h);
            ctx.fillStyle = scope.currentTheme.background;
            ctx.fillRect(0, 0, w, h);
            if(streams.electrics) {
                var throttleVal = parseInt(streams.electrics.throttle * 100);
                var brakeVal = parseInt(streams.electrics.brake * 100);
                var clutchVal = Math.round(streams.electrics.clutch * 100 + 0.49);
                var parkingVal = parseInt(streams.electrics.parkingbrake * 100);

                //clutch
                ctx.fillStyle = scope.currentTheme.clutch;
                ctx.fillRect(14,45,15,-clutchVal*0.4);

                //brake
                ctx.fillStyle = scope.currentTheme.brake;
                ctx.fillRect(33,45,15,-brakeVal*0.4);

                //throttle
                ctx.fillStyle = scope.currentTheme.throttle;
                ctx.fillRect(52,45,15,-throttleVal*0.4);

                //pbrake
                ctx.fillStyle = scope.currentTheme.pbrake;
                ctx.fillRect(71,45,15,-parkingVal*0.4);


                //addtext
                ctx.font='7px Arial';
                ctx.textAlign="center";

                ctx.fillStyle = scope.currentTheme.text;
                ctx.fillText(clutchVal,     21.5,52);
                ctx.fillText(brakeVal,      40.5,52);
                ctx.fillText(throttleVal,   59.5,52);
                ctx.fillText(parkingVal,    78.5,52);

                //add borders
                ctx.strokeStyle = scope.currentTheme.border;
                ctx.strokeRect(52,45,15,-40);
                ctx.strokeRect(33,45,15,-40);
                ctx.strokeRect(14,45,15,-40);
                ctx.strokeRect(71,45,15,-40);

                ctx.fillStyle = scope.currentTheme.text;
                ctx.textAlign="center";
                ctx.font='10px Arial';
                ctx.fillText("Pedals & Axis", 50, 62);
            }
        });

        scope.$on('ClassicUI', function (event, state) {
            if(state == "updateTheme") {
                scope.currentTheme = getTheme();
            }
        });

        function getTheme() {
            var themeStyles = parseInt(getDefaultValue("themeMode", 0));
            var tmpTheme;
            if(themeStyles == 0) {
                tmpTheme = {
                    background: 'rgba(255, 255, 255, 0.9)',
                    text: 'rgba(0, 0, 0, 0.9)',
                    border: 'rgba(0, 0, 0, 0.9)',

                    clutch: 'rgba(0, 0, 255, 0.5)',
                    brake: 'rgba(255, 0, 0, 0.5)',
                    throttle: 'rgba(0, 255, 0, 0.5)',
                    pbrake: 'rgba(255, 255, 0, 0.5)',
                };
            }
            if(themeStyles == 1) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.9)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(160, 160, 160)',

                    clutch: 'rgba(80, 80, 255, 0.5)',
                    brake: 'rgba(255, 80, 80, 0.5)',
                    throttle: 'rgba(80, 255, 80, 0.5)',
                    pbrake: 'rgba(255, 255, 80, 0.5)',
                };
            }
            if(themeStyles == 2) {
                tmpTheme = {
                    background: 'rgba(0, 0, 0, 0.43)',
                    text: 'rgba(255, 255, 255, 0.9)',
                    border: 'rgb(80, 80, 80)',

                    clutch: 'rgba(80, 80, 255, 0.5)',
                    brake: 'rgba(255, 80, 80, 0.5)',
                    throttle: 'rgba(80, 255, 80, 0.5)',
                    pbrake: 'rgba(255, 255, 80, 0.5)',
                };
            }
            return tmpTheme;
        }

        function pad(num, size) {
            var s = num+"";
            while (s.length < size) s = "0" + s;
            return s;
        }
        function getDefaultValue(type, defVal) {
            return localStorage.getItem("classicUI_" + type) || defVal;
        }
    }
  };
}]);



дай все размеры, цвета, отступы