design – Implementing something similar to the logic of a cascading style sheet engine

I am trying to implement something similar to the logic of CSS: a set of rules define which attributes every objects should have based on the state of the object and its ancestors.

After spending hours studying the problem and searching online, the best solution I could find has a cubic time complexity. I’m wondering if I can find better solutions, even tweaking the specifications slightly.

I’ll try to define some clear, simplified specifications for the kind of logic I need.

Specifications

Attributes, labels, objects, rules

An attribute is a unique ID (think of it as a string, like “width” or “height”). The set of attributes is known statically and can’t be expanded by the user.

A label is a a unique ID (think of it as a string, like “seen” or “favorite”). The set of labels is specified at runtime by the user.

The objects are nodes of a tree: each object has any number of children and (except for the root) a parent.
An object has a set of labels.
For every attribute a, every object o has a value o(a).

A rule has a priority, a value for some attributes and a query to match some objects.
For every attribute a, a rule r may or may not have a value r{a}.
The query matches objects based on the labels of an object and its ancestors. Examples of queries:

  • favorite matches every object with a label “favorite”.
  • highlighted current matches every object with a label “current”, that descends from an object with a label “highlighted”.
  • favorite+current seen * matches every object, that descends from an object with label “seen”, that descends from an object with a labels “favorite” and “current”.
Invariant

For every object o and every attribute a, the value of o(a) must be r{a}, where r is the rule with highest priority that matches o and that has a value r{a}.
Let’s assume an object’s attribute is always found: it’s not difficult to handle it otherwise.

Labels can be added to and removed from objects dynamically, during execution. When the labels are changed, attributes need to be recomputed in order to satisfy the invariant.


What I described is a simplification of how CSS works, using a slightly different terminology: in CSS a label is called a class; an object is called an element; a query is called a selector.

Attempted solution

I could find a very simple solution: every time a new label is added to or removed from an object, for each of its descendants (including itself) I check which rules match it, sort them by priority, then recompute the value for each attribute by iterating through the matching rules. Here the pseudo code:

function objectLabelsChanged( obj: object ) {
  for every object o of obj.descendants():  # it includes `obj` itself
    matchingRules = rules.filter( λr. r.match(o) )
                         .sort( λr. r.priority )

    for every attribute a:
      o(a) = matchingRules.filter( λr. r.has(a) )
                          .map( λr. r{a} )
                          .first()
}

This algorithm has a cubic complexity though: O(n*m*l). Number of objects (n) times number of attributes (m) times number of rules (l).

Questions

So my questions are:

  1. Is my solution asymptotically optimal?
  2. How can improved my algorithm? I’m interested in heuristics too.
  3. Are there alternative standards/definitions/languages/implementations/logic/algorithms to CSS, that offer similar logic? This seems like a pretty generic problem, but I couldn’t find any name for it besides CSS.
  4. Can you think of any variation of the problem, that could reduce the complexity while keeping a comparable expressive power?

Implementing libraries for a programming language

Implementing libraries for a programming language – Software Engineering Stack Exchange

c++ – Implementing perspective correct texture mapping in a Doom-like 3D software renderer in GLUT

For the last few weeks I have been making a 3D engine similar to Id Tech 1, ACKNEX, Build Engine and the like with GLUT and C++, and recently I started working with textures and texture mapping, this is when I ran into the problem that every 3D engine has to deal with: affine texture mapping.

I researched the methods of how to fix this, and they all take into account that you have access to the rasterization method, and in my case I just use glBindTexture() and glBegin(GL_QUADS) to render each wall, I just let GLUT do all the work for me.
Besides glTexCoord2f() to define the UV mapping of the texture, by the nature of the engine, I use the size and height of the wall to determine the amount of times the texture is repeated between the two triangles inside the trapezium, but beyond that, I don’t have access to the z-distance of each pixel in the polygon, I only have access to the distance of each horizontal edge of the wall inside the 3D space, this is what determines the perspective, and consequently the 2D position of the four vertices on the screen that will draw the wall.
With this in mind, what would be the best alternative to solve this problem?

Next is the method that draws each wall:

for(auto walld = depthBuffer.begin(); walld != depthBuffer.end(); walld++){
        glEnable(GL_TEXTURE_2D);
        
        float wdza = (*walld).dzb; //the Z distance of point A of the wall.
        float wdzb = (*walld).dza; //the Z distance of point B of the wall.
        
        float u = -(*walld).length; //U based on the wall length.
        float v = -(*walld).height; //V based on the wall height.

        glBindTexture (GL_TEXTURE_2D, texture);
        glBegin(GL_QUADS);

        glTexCoord2f(0, 0);
        glVertex2f((*walld).pa.x + 320, (*walld).pa.y + 240 + shearing);

        glTexCoord2f(u, 0);
        glVertex2f((*walld).pb.x + 320, (*walld).pb.y  + 240 + shearing);

        glTexCoord2f(u, v);
        glVertex2f((*walld).pc.x + 320, (*walld).pc.y  + 240 + shearing);

        glTexCoord2f(0, v);
        glVertex2f((*walld).pd.x + 320, (*walld).pd.y  + 240 + shearing);
        
        glEnd();
        glDisable(GL_TEXTURE_2D);
    }

(Translated by DeepL, in case something described is a bit confusing, keep this in mind).

c++ – Am I implementing S.O.L.I.D principles properly?

I am currently studying Object Oriented Design (OOD) and design patterns, and this hierarchy came into my mind, it simply makes a burger sandwich object, so I made it as follows (Read the comments in the code -there are some questions-):

//Bread Abstract Class
class Bread 
 {  
 public:
     string name; 
     int size; // because the bread have different sizes :D

     virtual Bread& getBread() = 0; // I made this a pure virtual function because 
                                    // I wanted the class to be abstract, was this a good idea?
                                    // because I think I broke the DRY concept by doing this.
     Bread(string name, int size)
         : name(name), size(size) {}
 };

 //Burger Abstract Class
 class Burger 
 {
 public:
     string type; 
     int size; //And the burgers of course :D

     virtual Burger& getBurger() = 0;  // As well as here!
     Burger(string type, int size)
         : type(type) ,size(size) {}
 };

//French Bread Concrete Class
 class frenchBread : public Bread 
 {
 public:
     Bread& getBread() override
     {
         return *this;
     }

     frenchBread(int size)
         :Bread("French Bread", size) {}
 };

 //White Bread Concrete Class
 class whiteBread : public Bread 
 {
 public:
     Bread& getBread() override
     {
         return *this;
     }

     whiteBread( int size)
         : Bread("White Bread", size) {}
 };

 //Vegeterian Base Class
 class vegieBurger : public Burger
 {
 public:
     Burger& getBurger () override
     {
         return *this;
     }

     vegieBurger (string name, int size)
     : Burger(name, size) {}

 };

 //Green Burger Derived Class From Vegeterian Burger Base Class
 class greenBurger : public vegieBurger 
 {
 public:
     greenBurger(int size)
         : vegieBurger("Green Burger", size) {}

 };

 //Non Vegeterian Burger Base Class
 class nonVegieBurger : public Burger 
 {
 public:
     Burger& getBurger()override
     {
         return *this;
     }

     nonVegieBurger(string name, int size)
         : Burger(name, size) {}

 };

 //Chicken Burger Derived Class From Non Vegeterian Base Class
 class chickenBurger: public nonVegieBurger 
 {
     chickenBurger(int size)
         : nonVegieBurger("Chicken Burger", size) {}

 };

 //Beef Burger Derived Class From Non Vegeterian Class
 class beefBurger : public nonVegieBurger 
 {
     beefBurger(int size)
         : nonVegieBurger("Beef Burger", size) {}

 };

 //Sandwich interface
 class I_Sandwich
 {
 public:
     virtual Bread& bread() = 0;
     virtual Burger& burger() = 0;
 };

 // Sandwich Class Contracts The Sandwich Interface 
 class sandwich : public I_Sandwich  {
 public: 
     Bread& bread1; 
     Burger& burger1; 

     sandwich(Bread& bread, Burger& burger)
         :bread1(bread), burger1(burger){}

     pair<Bread&, Burger&> getBreadAndBurger()
     {
         pair<Bread&, Burger&> result{bread1, burger1};
         return result;
     }

     Bread& bread () override
     {
         return bread1.getBread();
     }
     
     Burger& burger () override
     {
         return burger1.getBurger();
     }
 };

int main ()
{
    //And this is how I could make a green burger sandwich
    whiteBread bread(2);    // white bread of size 2 
    greenBurger burger(2);  // green burger of size 2
    sandwich greenBurgerWithWhiteBread(bread, burger);
}

I was trying to implement so concepts that I have learnt, like:

and I am planning to implement the builder pattern.

Noting that I am wholly new to this way of writing code because I didn’t put in mind abstractions and interfaces before.

The Question is:

  1. Is this approach good for implementing the concepts I stated above?
  2. Is there another pattern (or any other thing) that can be useful for implementing this particular hierarchy?

Implementing growth in Snake?

I’m new at this, so I thought I’d start simple. Snake. I started with pygame, just looking some things up, and I’ve now got movement, random fruit generation, and a score counter.

pygame.init()

size = width, height = (800, 440)
screen = pygame.display.set_mode(size)
pygame.display.set_caption('snake from scratch')

clock = pygame.time.Clock()

notBlack = (40,50,50)
white = (255,255,255)
red = (255,0,0)
blue = (0,0,255)
green = (0,255,0)

w = 20, 760

x1 = 400
y1 = 220
x1Velocity = 0
y1Velocity = 0
x2 = 0
y2 = 0

player = pygame.Rect(x1, y1, 20, 20)
fruit = pygame.Rect(x2, y2, 20, 20)
fruitOnScreen = False
score = 0

def roundTo(x, base):
    return base * round(x/base) #rounds to whatever you put as base

def offScreen(x, y):
    while x >= 760 or y >= 400:
        if x > 760:
            x -= 5
        if y > 400:
            y -= 5
        if x < 770 and y < 405:
            break
    return x, y #forces x and y pos back on screen

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False
            if event.key == pygame.K_LEFT:
                x1Velocity = -20
                y1Velocity = 0
            if event.key == pygame.K_RIGHT:
                x1Velocity = 20
                y1Velocity = 0
            if event.key == pygame.K_UP:
                x1Velocity = 0
                y1Velocity = -20
            if event.key == pygame.K_DOWN:
                x1Velocity = 0
                y1Velocity = 20

    x1 += x1Velocity
    y1 += y1Velocity
    
    player = pygame.Rect(x1, y1, 20, 20)
    fruit = pygame.Rect(x2, y2, 20, 20)
    collide = player.colliderect(fruit)

    if not fruitOnScreen:
        x2 = random.randrange(20, 760)
        y2 = random.randrange(20, 400)
        x2 = roundTo(x2, 20)
        y2 = roundTo(y2, 20)
        x2, y2 = offScreen(x2, y2)
        fruitOnScreen = True #Generates random coords for fruit
    elif collide:
        score += 1
        fruitOnScreen = False
        print(score)

    screen.fill(white)
    
    pygame.draw.rect(screen, red, (x2, y2, 20, 20))
    pygame.draw.rect(screen, blue, (x1, y1, 20, 20))
    pygame.draw.rect(screen, notBlack, (0, 0, 800, 440), 40) #Draws a 20pixel thick border
    pygame.display.update()
    clock.tick(8)

pygame.quit()
quit()

I think this is pretty good for not having much of any experience, but now I’m stuck. I want to have the body get longer, but I don’t know where to even start. Just looking at it, is it even possible to implement it using what I’ve already got?

java – Implementing Queue using Dynamic Circular Array

I am going through a course and after learning the theory I decided to implement the DS on my own. I write a few test cases and all operations seem to be working fine but once I tried to double check with the course’s solution, it is not clear if I am missing anything since my logic is not line by line the same 🙁

Resizing approach I took:

  • Doubling once full capacity is reach
  • Halving once number of items in the Queue decrease to 1/4 of capacity

Operations:

public E dequeue()
public void enqueue(E item)
public int size()
private boolean isFullCapacity()
private boolean isFourthCapacity()
private void resize(int newSize)
public boolean isEmpty()

If anyone can point me to where I can more thoroughly test, I would also appreciate it. I could not find any test suite on the internet. Would also appreciate general good practices feed back 🙂

public class QueueResizingArray <E> implements Queue<E> {

    private E() arr;
    private int size;
    private int front;
    private int end;

    private static final int INITIAL_CAPACITY = 6;
    private static final int INCREASE_FACTOR = 2;


    public QueueResizingArray(){
        this.arr = (E()) new Object(INITIAL_CAPACITY);
    }

    @Override
    public void enqueue(E item) {
        if(item == null)
            throw new IllegalArgumentException("item entered cannot be null");

        this.arr(front) = item;
        this.front = getNextPointerInCircularArray(this.front);
        this.size ++;


        if(isFullCapacity())
            resize(INCREASE_FACTOR * this.arr.length);

    }

    @Override
    public E dequeue() {
        if(this.isEmpty())
            throw new NoSuchElementException("Queue is empty when trying to dequeue");

        E item = this.arr(end);
        this.arr(end) = null;
        this.end = getNextPointerInCircularArray(this.end);
        this.size--;

        /*
        first condition added otherwise following will happen.
         , lets take as an example an array of length, arr.length = 3,
         and there is one item in array, size = 1, and we decide to dequeue this single item.
         size = 1 will decrement to 0 in the dequeue() method and the reach isFourthCapacity().
          at this point, the following check occurs. if ( size == arr.length/4) in this case
          since size = 1 and arr.length = 4, the check evaluates to if ( 0 == 0), triggering a resize even with no items present.
          if (0 == 0)
         incorrectly triggering shrinking even with no items present
         0 (size)/3 (array.length) = 0 (
         */
        if(this.size > 0 && isFourthCapacity())
            resize(this.arr.length/2);

        return item;
    }

    @Override
    public boolean isEmpty() {
        return this.size == 0;
    }

    @Override
    public int size() {
        return this.size;
    }

    private boolean isFullCapacity(){
        return this.size == this.arr.length;
    }

    private boolean isFourthCapacity(){
        return this.size == this.arr.length/4;
    }


    private void resize(int newArrLength){
        E() newArr = (E()) new Object(newArrLength);
        int insertIndex = 0;
        int tempEnd = this.end;

        do{
            newArr(insertIndex) = this.arr(tempEnd);
            tempEnd = getNextPointerInCircularArray(tempEnd);
            insertIndex++;
        }while(this.front != tempEnd);

        //the reason why i move end is because  if halving, end will lag front and we can increment end to touch all items we need to copy. I think we could also decrement front
        //TODO we need a do while to move end one away from front, below does not work because when full, end will equal front not triggering copying of elements
//        while(this.front != tempEnd){
//            newArr(insertIndex) = this.arr(tempEnd);
//            tempEnd = getNextPointerInCircularArray(tempEnd);
//            insertIndex++;
//        }

        //resetting indexes after resizing
        this.front = this.size;
        this.end = 0;
        //setting new array
        this.arr = newArr;
    }

    private int getNextPointerInCircularArray(int reference){
        return (reference + 1) % this.arr.length;
    }
}

Tests:

public class Test {

    @org.junit.Test
    public void testMyCircularResizingArraySolution(){
        Queue<Integer> queue = new QueueResizingArray<>();

        //enqueue
        queue.enqueue(1);

        //assert
        Assert.assertEquals(1, queue.size());

        //dequeue
        int item1 = queue.dequeue();
        Assert.assertEquals(1, item1);
        Assert.assertEquals(0, queue.size());


        //6 enqueues
        queue.enqueue(1);
        queue.enqueue(1);
        queue.enqueue(1);
        queue.enqueue(-9);
        queue.enqueue(2);
        queue.enqueue(7);

        //last enqueue should have triggered doubling of circular array

        int item2 = queue.dequeue();
        Assert.assertEquals(1, item2);

        Assert.assertEquals(5, queue.size());


        int item3 = queue.dequeue();
        Assert.assertEquals(1, item3);

        Assert.assertEquals(4, queue.size());


        //will trigger halving
        int item4 = queue.dequeue();
        Assert.assertEquals(1, item4);

        Assert.assertEquals(3, queue.size());



        int item5 = queue.dequeue();
        Assert.assertEquals(-9, item5);

        Assert.assertEquals(2, queue.size());


        int item6 = queue.dequeue();
        Assert.assertEquals(2, item6);

        Assert.assertEquals(1, queue.size());



        int item7 = queue.dequeue();
        Assert.assertEquals(7, item7);

        Assert.assertEquals(0, queue.size());

   }

}

design – Implementing Event Sourcing persistence over streaming broker

I implement an event sourcing system over a streaming broker (Apache Pulsar), and I am concerned regarding the transactionnality of the persistence mechanism.

Currently my event system works as follows: I have Commands which, given an Aggregate‘s events and some parameters produce new Events.

To achieve persistence, I should have a system which is able to retrieve all the Events from an Aggregate (or a given key), and store atomically a set of Events (preventing concurrent stores).

In order to do that, I had the following plan:

  1. Create a consumer over the topic/key of the concerned Aggregate
  2. Open a transaction (Apache Pulsar allows it, to atomically publish a set of messages at once)
  3. Load previous messages/Events (thanks to PrestoSQL/Trinio)
  4. Forward the fetched Events to the Command
  5. Push the new Events in the broker
  6. Check whether the consumer (1) received something, if so, abort the transaction
  7. Ack the messages/Events
  8. Commit the transaction

In my opinion it is quite complicated, and concurrency can happen between (6) and (8).
Is it the right way to implement an event sourcing persistence over a streaming broker? or is it flawed by design/essence?

reinventing the wheel – Implementing conditinional execution in Python

I found abandoned project on GitHub and curious is it possible to implement part of it on just Python?

Goal:

  • Call functions only under some condition.
  • Track if ANY of inner function were triggered.
  • Reuse variables from the same scope to be more flexible with inner functions calls.

I have PoC working, but I wonder is any better algorithmic approach to do the same in Python? Most obvious way to do something similar to bellow. But is there more elegant way to get rid of repeating if ...: processed = True pattern?

def boo(a, c):
  # do something
  return True

def foo(a, b, c):
  # do something more
  return True

def setup(a, b, c):
   processed = False

   if ((a == "boo") & (c == 1)):
      if boo(a, c):
         processed = True

   if ((a == "boo") & ((c == 2) | (b == 3))):
      if foo(a, b, c):
         processed = True
   ...
   return processed

c# – Verify implementing Microsoft Graph 4.0.0 for SSO in Azure is implemented correctly

I originally posted this on SO, and I know cross-linking is generally frowned upon. But, I am not sure if this falls under question or code review because the code works where I do not know if it is implemented correctly. Anyways, here it is:

https://stackoverflow.com/questions/68868685/need-help-demystifying-the-new-feature-introduced-on-microsoft-graph-4-0-0

Question:

Do we need to acquire the access token from Microsoft.Graph using either silent or interactive modes? From what I can tell the answer is, No. (see Context below)

The new implementation seems to be drastically scaled down with the whole idea of silent and interactive token retrieval being removed. Is this correct?

using Azure.Identity;
using Microsoft.Graph;
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string() args)
        {
            var scopes = new() { "User.Read" };

            // Multi-tenant apps can use "common",
            // single-tenant apps must use the tenant ID from the Azure portal
            var tenantId = "SomeGuid";

            // Value from app registration
            var clientId = "SomeGuid";

            var options = new InteractiveBrowserCredentialOptions
            {
                TenantId = tenantId,
                ClientId = clientId,
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                // MUST be http://localhost or http://localhost:PORT
                // See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core
                RedirectUri = new Uri("http://localhost:1234"),
            };

            // https://docs.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential
            var interactiveCredential = new InteractiveBrowserCredential(options);

            var graphClient = new GraphServiceClient(interactiveCredential, scopes);
            
            // Interactive browser login occurs here.
            var me = graphClient.Me.Request().GetAsync().Result;

            // Printing the results
            Console.WriteLine("-------- Data from call to MS Graph --------");
            Console.Write(Environment.NewLine);
            Console.WriteLine($"Id: {me.Id}");
            Console.WriteLine($"Display Name: {me.DisplayName}");
            Console.WriteLine($"Email: {me.Mail}");
            //Console.ReadLine();
        }
    }
}

Context:

As part of our routine maintenance, I was tasked with upgrading our NuGet packages on a Winforms desktop application that is running in Azure and whose users are in Azure Active Directory Services (AADS). One of the packages, Microsoft.Graph, had a major version change. https://www.nuget.org/packages/Microsoft.Graph/4.0.0

The documentation on it indicated a new feature for handling the TokenCredentialClass. https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/4.0.0/docs/upgrade-to-v4.md#new-capabilities

From what I can tell, there is a separate and distinct break on how the token is retrieved. Previously, we followed the method provided here: https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-windows-desktop#add-the-code-to-initialize-msal

Old way:

using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string() args)
        {
            _PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                    .WithRedirectUri("http://localhost:1234")
                    .WithAuthority(AzureCloudInstance.AzurePublic, TenantId)
                    .Build();

            // We sign the user in here
            bolIsAutorizeSSO = CallMicrosoftSSO().GetAwaiter().GetResult();
            InteractiveAuthenticationProvider = new InteractiveAuthenticationProvider(PublicClientApp, Scopes);
            GraphServiceClient = new Microsoft.Graph.GraphServiceClient(InteractiveAuthenticationProvider);

            if (bolIsAutorizeSSO)
            {
                // We also signt the user in here.
                var User = GraphServiceClient.Me.Request().GetAsync().Result;

                // Printing the results
                Console.WriteLine("-------- Data from call to MS Graph --------");
                Console.Write(Environment.NewLine);
                Console.WriteLine($"Id: {User.Id}");
                Console.WriteLine($"Display Name: {User.DisplayName}");
                Console.WriteLine($"Email: {User.Mail}");
            }
            else
            {
                // signout
                Console.ReadLine();
            }
        }

        public static async Task<bool> CallMicrosoftSSO()
        {
            AuthenticationResult authResult = null;
            var app = PublicClientApp;
            var accounts = await app.GetAccountsAsync();

            try
            {
                authResult = await app.AcquireTokenInteractive(Scopes)
                    .WithAccount(accounts.FirstOrDefault())
                    .WithPrompt(Microsoft.Identity.Client.Prompt.ForceLogin)
                    .ExecuteAsync();
            }
            catch (MsalUiRequiredException _Exception)
            {
                // A MsalUiRequiredException happened on AcquireTokenSilent. 
                // This indicates you need to call AcquireTokenInteractive to acquire a token.
                
                Console.WriteLine(_Exception.Message);
            }
            catch (MsalException msalex)
            {
                if (msalex.ErrorCode != "authentication_canceled")
                {
                    Console.WriteLine(msalex.Message);
                }
            }
            catch (Exception _Exception)
            {
                Console.WriteLine(_Exception.Message);
            }

            if (authResult != null)
            {
                return true;
            }
            return false;
        }

        private static string ClientId = "SomeGuid";
        private static string TenantId = "SomeGuid";
        private static string() Scopes = new string() { "User.Read" };
        private static Microsoft.Graph.GraphServiceClient GraphServiceClient;
        private static bool bolIsAutorizeSSO = false;
        private static InteractiveAuthenticationProvider InteractiveAuthenticationProvider;

        private static IPublicClientApplication _PublicClientApp;
        public static IPublicClientApplication PublicClientApp { get { return _PublicClientApp; } }
    }
}

I am struggling to make sense of it. Partly because the feature is brand new and there are very few code samples up on the internet that say do it this way. What I have found seems to point me back to what we already are using (more on that in a bit). So, the examples may not yet be fully updated.

DreamProxies - Cheapest USA Elite Private Proxies 100 Cheapest USA Private Proxies Buy 200 Cheap USA Private Proxies 400 Best Private Proxies Cheap 1000 USA Private Proxies 2000 USA Private Proxies 5000 Cheap USA Private Proxies ExtraProxies.com - Buy Cheap Private Proxies Buy 50 Private Proxies Buy 100 Private Proxies Buy 200 Private Proxies Buy 500 Private Proxies Buy 1000 Private Proxies Buy 2000 Private Proxies Proxies123.com